support azure elb sync

This commit is contained in:
tb365
2021-06-23 17:18:45 +08:00
parent 11b04454f2
commit bb10f3ef3a
32 changed files with 2614 additions and 28 deletions
+34 -14
View File
@@ -639,6 +639,31 @@ type ICloudLoadbalancer interface {
GetILoadBalancerListenerById(listenerId string) (ICloudLoadbalancerListener, error)
}
type ICloudLoadbalancerRedirect interface {
GetRedirect() string
GetRedirectCode() int64
GetRedirectScheme() string
GetRedirectHost() string
GetRedirectPath() string
}
type ICloudloadbalancerHealthCheck interface {
GetHealthCheck() string
GetHealthCheckType() string
GetHealthCheckTimeout() int
GetHealthCheckInterval() int
GetHealthCheckRise() int
GetHealthCheckFail() int
GetHealthCheckReq() string
GetHealthCheckExp() string
// HTTP && HTTPS
GetHealthCheckDomain() string
GetHealthCheckURI() string
GetHealthCheckCode() string
}
type ICloudLoadbalancerListener interface {
IVirtualResource
@@ -650,24 +675,13 @@ type ICloudLoadbalancerListener interface {
GetAclId() string
GetEgressMbps() int
GetHealthCheck() string
GetHealthCheckType() string
GetHealthCheckTimeout() int
GetHealthCheckInterval() int
GetHealthCheckRise() int
GetHealthCheckFail() int
GetHealthCheckReq() string
GetHealthCheckExp() string
GetBackendGroupId() string
GetBackendServerPort() int
GetClientIdleTimeout() int
GetBackendConnectTimeout() int
// HTTP && HTTPS
GetHealthCheckDomain() string
GetHealthCheckURI() string
GetHealthCheckCode() string
CreateILoadBalancerListenerRule(rule *SLoadbalancerListenerRule) (ICloudLoadbalancerListenerRule, error)
GetILoadBalancerListenerRuleById(ruleId string) (ICloudLoadbalancerListenerRule, error)
GetILoadbalancerListenerRules() ([]ICloudLoadbalancerListenerRule, error)
@@ -683,6 +697,10 @@ type ICloudLoadbalancerListener interface {
GetTLSCipherPolicy() string
HTTP2Enabled() bool
// http redirect
ICloudLoadbalancerRedirect
ICloudloadbalancerHealthCheck
Start() error
Stop() error
Sync(ctx context.Context, listener *SLoadbalancerListener) error
@@ -692,6 +710,8 @@ type ICloudLoadbalancerListener interface {
type ICloudLoadbalancerListenerRule interface {
IVirtualResource
// http redirect
ICloudLoadbalancerRedirect
IsDefault() bool
GetDomain() string
@@ -19,6 +19,8 @@ import (
"database/sql"
"fmt"
"yunion.io/x/pkg/utils"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
@@ -738,6 +740,15 @@ func (lbr *SLoadbalancerListenerRule) constructFieldsFromCloudListenerRule(userC
lbr.Path = extRule.GetPath()
lbr.Status = extRule.GetStatus()
lbr.Condition = extRule.GetCondition()
if utils.IsInStringArray(extRule.GetRedirect(), []string{api.LB_REDIRECT_OFF, api.LB_REDIRECT_RAW}) {
lbr.Redirect = extRule.GetRedirect()
lbr.RedirectCode = int(extRule.GetRedirectCode())
lbr.RedirectScheme = extRule.GetRedirectScheme()
lbr.RedirectHost = extRule.GetRedirectHost()
lbr.RedirectPath = extRule.GetRedirectPath()
}
if groupId := extRule.GetBackendGroupId(); len(groupId) > 0 {
if lbr.GetProviderName() == api.CLOUD_PROVIDER_HUAWEI {
group, err := db.FetchByExternalId(HuaweiCachedLbbgManager, groupId)
@@ -1004,9 +1004,23 @@ func (lblis *SLoadbalancerListener) constructFieldsFromCloudListener(userCred mc
lblis.HealthCheckInterval = extListener.GetHealthCheckInterval()
lblis.HealthCheckRise = extListener.GetHealthCheckRise()
lblis.HealthCheckFall = extListener.GetHealthCheckFail()
lblis.HealthCheckDomain = extListener.GetHealthCheckDomain()
lblis.HealthCheckURI = extListener.GetHealthCheckURI()
lblis.HealthCheckExp = extListener.GetHealthCheckExp()
lblis.HealthCheckHttpCode = extListener.GetHealthCheckCode()
}
}
if utils.IsInStringArray(extListener.GetRedirect(), []string{api.LB_REDIRECT_OFF, api.LB_REDIRECT_RAW}) {
lblis.Redirect = extListener.GetRedirect()
lblis.RedirectCode = int(extListener.GetRedirectCode())
lblis.RedirectScheme = extListener.GetRedirectScheme()
lblis.RedirectHost = extListener.GetRedirectHost()
lblis.RedirectPath = extListener.GetRedirectPath()
}
lblis.ClientIdleTimeout = extListener.GetClientIdleTimeout()
lblis.BackendConnectTimeout = extListener.GetBackendConnectTimeout()
lblis.BackendServerPort = extListener.GetBackendServerPort()
switch lblis.ListenerType {
@@ -1040,6 +1054,7 @@ func (lblis *SLoadbalancerListener) constructFieldsFromCloudListener(userCred mc
lblis.StickySessionCookieTimeout = extListener.GetStickySessionCookieTimeout()
}
}
lblis.EnableHttp2 = extListener.HTTP2Enabled()
lblis.XForwardedFor = extListener.XForwardedForEnabled()
lblis.Gzip = extListener.GzipEnabled()
}
@@ -27,6 +27,7 @@ import (
type SLoadbalancerHTTPListener struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
multicloud.AliyunTags
lb *SLoadbalancer
@@ -368,3 +369,11 @@ func (listerner *SLoadbalancerHTTPListener) Sync(ctx context.Context, lblis *clo
func (listerner *SLoadbalancerHTTPListener) GetProjectId() string {
return listerner.lb.GetProjectId()
}
func (listerner *SLoadbalancerHTTPListener) GetClientIdleTimeout() int {
return 0
}
func (listerner *SLoadbalancerHTTPListener) GetBackendConnectTimeout() int {
return 0
}
@@ -27,6 +27,7 @@ import (
type SLoadbalancerHTTPSListener struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
multicloud.AliyunTags
lb *SLoadbalancer
@@ -398,3 +399,11 @@ func (listerner *SLoadbalancerHTTPSListener) Sync(ctx context.Context, lblis *cl
func (listerner *SLoadbalancerHTTPSListener) GetProjectId() string {
return listerner.lb.GetProjectId()
}
func (listerner *SLoadbalancerHTTPSListener) GetClientIdleTimeout() int {
return 0
}
func (listerner *SLoadbalancerHTTPSListener) GetBackendConnectTimeout() int {
return 0
}
@@ -27,6 +27,7 @@ import (
type SLoadbalancerListenerRule struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
multicloud.AliyunTags
httpListener *SLoadbalancerHTTPListener
httpsListener *SLoadbalancerHTTPSListener
@@ -28,6 +28,7 @@ import (
type SLoadbalancerTCPListener struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
multicloud.AliyunTags
lb *SLoadbalancer
@@ -357,3 +358,11 @@ func (listerner *SLoadbalancerTCPListener) Sync(ctx context.Context, lblis *clou
func (listerner *SLoadbalancerTCPListener) GetProjectId() string {
return listerner.lb.GetProjectId()
}
func (listerner *SLoadbalancerTCPListener) GetClientIdleTimeout() int {
return 0
}
func (listerner *SLoadbalancerTCPListener) GetBackendConnectTimeout() int {
return 0
}
@@ -27,6 +27,7 @@ import (
type SLoadbalancerUDPListener struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
multicloud.AliyunTags
lb *SLoadbalancer
@@ -283,3 +284,11 @@ func (listerner *SLoadbalancerUDPListener) Sync(ctx context.Context, lblis *clou
func (listerner *SLoadbalancerUDPListener) GetProjectId() string {
return listerner.lb.GetProjectId()
}
func (listerner *SLoadbalancerUDPListener) GetClientIdleTimeout() int {
return 0
}
func (listerner *SLoadbalancerUDPListener) GetBackendConnectTimeout() int {
return 0
}
@@ -27,6 +27,7 @@ import (
type SLoadbalancerHTTPListener struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
multicloud.ApsaraTags
lb *SLoadbalancer
@@ -368,3 +369,11 @@ func (listerner *SLoadbalancerHTTPListener) Sync(ctx context.Context, lblis *clo
func (listerner *SLoadbalancerHTTPListener) GetProjectId() string {
return ""
}
func (listerner *SLoadbalancerHTTPListener) GetClientIdleTimeout() int {
return 0
}
func (listerner *SLoadbalancerHTTPListener) GetBackendConnectTimeout() int {
return 0
}
@@ -27,6 +27,7 @@ import (
type SLoadbalancerHTTPSListener struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
multicloud.ApsaraTags
lb *SLoadbalancer
@@ -398,3 +399,11 @@ func (listerner *SLoadbalancerHTTPSListener) Sync(ctx context.Context, lblis *cl
func (listerner *SLoadbalancerHTTPSListener) GetProjectId() string {
return ""
}
func (listerner *SLoadbalancerHTTPSListener) GetClientIdleTimeout() int {
return 0
}
func (listerner *SLoadbalancerHTTPSListener) GetBackendConnectTimeout() int {
return 0
}
@@ -27,6 +27,7 @@ import (
type SLoadbalancerListenerRule struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
multicloud.ApsaraTags
httpListener *SLoadbalancerHTTPListener
httpsListener *SLoadbalancerHTTPSListener
@@ -28,6 +28,7 @@ import (
type SLoadbalancerTCPListener struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
multicloud.ApsaraTags
lb *SLoadbalancer
@@ -357,3 +358,11 @@ func (listerner *SLoadbalancerTCPListener) Sync(ctx context.Context, lblis *clou
func (listerner *SLoadbalancerTCPListener) GetProjectId() string {
return ""
}
func (listerner *SLoadbalancerTCPListener) GetClientIdleTimeout() int {
return 0
}
func (listerner *SLoadbalancerTCPListener) GetBackendConnectTimeout() int {
return 0
}
@@ -27,6 +27,7 @@ import (
type SLoadbalancerUDPListener struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
multicloud.ApsaraTags
lb *SLoadbalancer
@@ -283,3 +284,11 @@ func (listerner *SLoadbalancerUDPListener) Sync(ctx context.Context, lblis *clou
func (listerner *SLoadbalancerUDPListener) GetProjectId() string {
return ""
}
func (listerner *SLoadbalancerUDPListener) GetClientIdleTimeout() int {
return 0
}
func (listerner *SLoadbalancerUDPListener) GetBackendConnectTimeout() int {
return 0
}
@@ -35,6 +35,7 @@ import (
type SElbListener struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
multicloud.AwsTags
region *SRegion
lb *SElb
@@ -442,6 +443,14 @@ func (self *SElbListener) HTTP2Enabled() bool {
return false
}
func (self *SElbListener) GetClientIdleTimeout() int {
return 0
}
func (self *SElbListener) GetBackendConnectTimeout() int {
return 0
}
func (self *SElbListener) Start() error {
return nil
}
@@ -33,6 +33,7 @@ import (
type SElbListenerRule struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
multicloud.AwsTags
listener *SElbListener
region *SRegion
+1 -1
View File
@@ -965,7 +965,7 @@ func (self *SAzureClient) GetCapabilities() []string {
cloudprovider.CLOUD_CAPABILITY_PROJECT,
cloudprovider.CLOUD_CAPABILITY_COMPUTE,
cloudprovider.CLOUD_CAPABILITY_NETWORK,
// cloudprovider.CLOUD_CAPABILITY_LOADBALANCER,
cloudprovider.CLOUD_CAPABILITY_LOADBALANCER,
cloudprovider.CLOUD_CAPABILITY_OBJECTSTORE,
cloudprovider.CLOUD_CAPABILITY_RDS,
cloudprovider.CLOUD_CAPABILITY_CACHE,
+663
View File
@@ -0,0 +1,663 @@
package azure
import (
"context"
"strings"
"github.com/pkg/errors"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/pkg/utils"
)
type SLoadbalancer struct {
region *SRegion
lbbgs []cloudprovider.ICloudLoadbalancerBackendGroup
listeners []cloudprovider.ICloudLoadbalancerListener
Name string `json:"name"`
ID string `json:"id"`
Etag string `json:"etag"`
Type string `json:"type"`
Tags map[string]string `json:"tags"`
Location string `json:"location"`
Properties SLoadbalancerProperties `json:"properties"`
Sku Sku `json:"sku"`
}
func (self *SLoadbalancer) GetId() string {
return self.ID
}
func (self *SLoadbalancer) GetName() string {
return self.Name
}
func (self *SLoadbalancer) GetGlobalId() string {
return self.GetId()
}
func (self *SLoadbalancer) GetStatus() string {
switch self.Properties.ProvisioningState {
case "Deleting":
return api.LB_STATUS_DELETING
case "Failed":
return api.LB_STATUS_START_FAILED
case "Updating":
return api.LB_SYNC_CONF
}
switch self.Properties.OperationalState {
case "Running":
return api.LB_STATUS_ENABLED
case "Stopped":
return api.LB_STATUS_DISABLED
case "Starting", "Stopping":
return api.LB_SYNC_CONF
default:
if self.Properties.ProvisioningState == "Succeeded" {
return api.LB_STATUS_ENABLED
}
return api.LB_STATUS_UNKNOWN
}
}
func (self *SLoadbalancer) Refresh() error {
lb, err := self.region.GetILoadBalancerById(self.GetId())
if err != nil {
return errors.Wrap(err, "GetILoadBalancerById.Refresh")
}
err = jsonutils.Update(self, lb)
if err != nil {
return errors.Wrap(err, "jsonutils.Update")
}
self.lbbgs = nil
self.listeners = nil
return nil
}
func (self *SLoadbalancer) IsEmulated() bool {
return false
}
func (self *SLoadbalancer) GetSysTags() map[string]string {
data := map[string]string{}
data["loadbalance_type"] = self.Type
data["properties"] = jsonutils.Marshal(self.Properties).String()
return data
}
func (self *SLoadbalancer) GetTags() (map[string]string, error) {
return self.Tags, nil
}
func (self *SLoadbalancer) SetTags(tags map[string]string, replace bool) error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "SetTags")
}
func (self *SLoadbalancer) GetProjectId() string {
return getResourceGroup(self.ID)
}
func (self *SLoadbalancer) getAddresses() [][]string {
ret := [][]string{[]string{}, []string{}}
for _, fip := range self.Properties.FrontendIPConfigurations {
eip := fip.Properties.PublicIPAddress
if eip != nil && len(eip.Properties.IPAddress) > 0 {
ret[0] = append(ret[0], fip.Properties.PublicIPAddress.Properties.IPAddress)
continue
}
if len(fip.Properties.PrivateIPAddress) > 0 {
ret[1] = append(ret[1], fip.Properties.PrivateIPAddress)
continue
}
}
return ret
}
func (self *SLoadbalancer) GetAddress() string {
ips := self.getAddresses()
if len(ips[0]) > 0 {
return ips[0][0]
} else if len(ips[1]) > 0 {
return ips[1][0]
} else {
return ""
}
}
func (self *SLoadbalancer) GetAddressType() string {
ips := self.getAddresses()
if len(ips[0]) > 0 {
return api.LB_ADDR_TYPE_INTERNET
} else if len(ips[1]) > 0 {
return api.LB_ADDR_TYPE_INTRANET
} else {
return api.LB_ADDR_TYPE_INTRANET
}
}
func (self *SLoadbalancer) GetNetworkType() string {
return api.LB_NETWORK_TYPE_VPC
}
func (self *SLoadbalancer) getNetworkIds() []string {
ret := []string{}
for _, fip := range self.Properties.FrontendIPConfigurations {
subnet := fip.Properties.Subnet
if len(subnet.ID) > 0 {
ret = append(ret, subnet.ID)
}
}
return ret
}
func (self *SLoadbalancer) getLbbgNetworkIds() []string {
ret := []string{}
for _, b := range self.Properties.BackendAddressPools {
bips := b.Properties.BackendIPConfigurations
if len(bips) > 0 {
for _, ip := range bips {
if strings.Contains(ip.ID, "Microsoft.Network/networkInterfaces") {
nic, _ := self.region.GetNetworkInterface(strings.Split(ip.ID, "/ipConfigurations")[0])
if nic != nil && len(nic.Properties.IPConfigurations) > 0 {
ipc := nic.Properties.IPConfigurations[0]
if len(ipc.Properties.Subnet.ID) > 0 {
return []string{ipc.Properties.Subnet.ID}
}
}
}
}
}
}
return ret
}
func (self *SLoadbalancer) GetNetworkIds() []string {
return self.getNetworkIds()
}
func (self *SLoadbalancer) GetVpcId() string {
if self.Type == "Microsoft.Network/loadBalancers" {
subnets := self.GetNetworkIds()
if len(subnets) == 0 {
subnets = self.getLbbgNetworkIds()
}
if len(subnets) > 0 {
network, err := self.region.GetNetwork(subnets[0])
if network != nil {
return strings.Split(network.GetId(), "/subnets")[0]
}
log.Errorf("GetNetwork %s: %s", subnets[0], err)
}
} else {
gips := self.Properties.GatewayIPConfigurations
for i := range gips {
netId := gips[i].Properties.Subnet.ID
if len(netId) > 0 {
network, err := self.region.GetNetwork(netId)
if network != nil {
return strings.Split(network.GetId(), "/subnets")[0]
}
log.Errorf("GetNetwork %s: %s", netId, err)
}
}
}
return ""
}
func (self *SLoadbalancer) GetZoneId() string {
ips := self.Properties.FrontendIPConfigurations
if len(ips) > 0 && len(ips[0].Zones) > 0 {
return ips[0].Zones[0]
}
return ""
}
func (self *SLoadbalancer) GetZone1Id() string {
ips := self.Properties.FrontendIPConfigurations
if len(ips) > 0 && len(ips[0].Zones) > 1 {
return ips[0].Zones[1]
}
return ""
}
func (self *SLoadbalancer) GetLoadbalancerSpec() string {
if len(self.Properties.Sku.Name) > 0 {
return self.Properties.Sku.Name
}
if len(self.Sku.Name) > 0 {
return self.Sku.Name
}
return ""
}
func (self *SLoadbalancer) GetChargeType() string {
return api.LB_CHARGE_TYPE_POSTPAID
}
func (self *SLoadbalancer) GetEgressMbps() int {
return 0
}
func (self *SLoadbalancer) getEipIds() []string {
ret := []string{}
for _, fip := range self.Properties.FrontendIPConfigurations {
eip := fip.Properties.PublicIPAddress
if eip != nil && len(eip.ID) > 0 {
ret = append(ret, eip.ID)
continue
}
}
return ret
}
func (self *SLoadbalancer) GetIEIP() (cloudprovider.ICloudEIP, error) {
eips := self.getEipIds()
if len(eips) > 0 {
return self.region.GetIEipById(eips[0])
}
return nil, nil
}
func (self *SLoadbalancer) Delete(ctx context.Context) error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "Delete")
}
func (self *SLoadbalancer) Start() error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "Start")
}
func (self *SLoadbalancer) Stop() error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "Stop")
}
/*
应用型LB urlPathMapsdefaultBackendAddressPool+defaultBackendHttpSettings+requestRoutingRules+httpListeners= Onecloud监听器
4层LB: loadBalancingRules(前端) = Onecloud监听器
*/
func (self *SLoadbalancer) GetILoadBalancerListeners() ([]cloudprovider.ICloudLoadbalancerListener, error) {
if self.listeners != nil {
return self.listeners, nil
}
var err error
if self.Type == "Microsoft.Network/applicationGateways" {
self.listeners, err = self.getAppLBListeners()
} else {
self.listeners, err = self.getNetworkLBListeners()
}
return self.listeners, err
}
func (self *SLoadbalancer) getFrontendIPConfiguration(id string) *FrontendIPConfiguration {
fips := self.Properties.FrontendIPConfigurations
for i := range fips {
if fips[i].ID == id {
return &fips[i]
}
}
log.Debugf("getFrontendIPConfiguration %s not found", id)
return nil
}
func (self *SLoadbalancer) getHttpListener(id string) *HTTPListener {
ss := self.Properties.HTTPListeners
for i := range ss {
if ss[i].ID == id {
return &ss[i]
}
for j := range ss[i].Properties.RequestRoutingRules {
if ss[i].Properties.RequestRoutingRules[j].ID == id {
return &ss[i]
}
}
}
log.Debugf("getHttpListener %s not found", id)
return nil
}
func (self *SLoadbalancer) getBackendAddressPool(id string) *BackendAddressPool {
ss := self.Properties.BackendAddressPools
for i := range ss {
if ss[i].ID == id {
return &ss[i]
}
}
log.Debugf("getBackendAddressPool %s not found", id)
return nil
}
func (self *SLoadbalancer) getBackendHTTPSettingsCollection(id string) *BackendHTTPSettingsCollection {
ss := self.Properties.BackendHTTPSettingsCollection
for i := range ss {
if ss[i].ID == id {
return &ss[i]
}
}
log.Debugf("getBackendHTTPSettingsCollection %s not found", id)
return nil
}
func (self *SLoadbalancer) getRedirectConfiguration(id string) *RedirectConfiguration {
ss := self.Properties.RedirectConfigurations
for i := range ss {
if ss[i].ID == id {
return &ss[i]
}
}
log.Debugf("getRedirectConfiguration %s not found", id)
return nil
}
func (self *SLoadbalancer) getProbe(id string) *Probe {
ss := self.Properties.Probes
for i := range ss {
if ss[i].ID == id {
return &ss[i]
}
}
log.Debugf("getProbe %s not found", id)
return nil
}
func (self *SLoadbalancer) getFrontendPort(id string) *FrontendPort {
ss := self.Properties.FrontendPorts
for i := range ss {
if ss[i].ID == id {
return &ss[i]
}
}
log.Debugf("getFrontendPort %s not found", id)
return nil
}
func (self *SLoadbalancer) getRequestRoutingRule(id string) *RequestRoutingRule {
ss := self.Properties.RequestRoutingRules
for i := range ss {
if ss[i].ID == id {
return &ss[i]
}
}
log.Debugf("getRequestRoutingRule %s not found", id)
return nil
}
/*
应用型LB urlPathMapsdefaultBackendAddressPool+defaultBackendHttpSettings+requestRoutingRules+httpListeners= Onecloud监听器
*/
func (self *SLoadbalancer) getAppLBListeners() ([]cloudprovider.ICloudLoadbalancerListener, error) {
lbls := []cloudprovider.ICloudLoadbalancerListener{}
for i := range self.Properties.URLPathMaps {
u := self.Properties.URLPathMaps[i]
lbl := self.getAppLBListener(&u)
if lbl != nil {
lbls = append(lbls, lbl)
}
}
return lbls, nil
}
func (self *SLoadbalancer) getAppLBListener(u *URLPathMap) *SLoadBalancerListener {
var redirect *RedirectConfiguration
var listener *HTTPListener
var fp *FrontendIPConfiguration
var fpp *FrontendPort
if len(u.Properties.RequestRoutingRules) == 0 {
return nil
}
if u.Properties.DefaultRedirectConfiguration != nil {
redirect = self.getRedirectConfiguration(u.Properties.DefaultRedirectConfiguration.ID)
}
// httpListener, urlPathMap
rrr := self.getRequestRoutingRule(u.Properties.RequestRoutingRules[0].ID)
// frontendPort, frontendIPConfiguration, sslCertificate, requestRoutingRules
listener = self.getHttpListener(rrr.Properties.HTTPListener.ID)
// frontendPorts
fp = self.getFrontendIPConfiguration(listener.Properties.FrontendIPConfiguration.ID)
fpp = self.getFrontendPort(listener.Properties.FrontendPort.ID)
// 配置有异常??
if fpp == nil || listener == nil {
return nil
}
var backendGroup *BackendAddressPool
if u.Properties.DefaultBackendAddressPool != nil {
backendGroup = self.getBackendAddressPool(u.Properties.DefaultBackendAddressPool.ID)
}
var backendSetting *BackendHTTPSettingsCollection
var backendPort int
if u.Properties.DefaultBackendHTTPSettings != nil {
backendSetting = self.getBackendHTTPSettingsCollection(u.Properties.DefaultBackendHTTPSettings.ID)
backendPort = backendSetting.Properties.Port
}
var healthcheck *Probe
if backendSetting != nil && backendSetting.Properties.Probe != nil {
healthcheck = self.getProbe(backendSetting.Properties.Probe.ID)
}
return &SLoadBalancerListener{
lb: self,
fp: fp,
listener: listener,
backendSetting: backendSetting,
backendGroup: backendGroup,
redirect: redirect,
healthcheck: healthcheck,
Name: u.Name,
ID: u.ID,
ProvisioningState: u.Properties.ProvisioningState,
IPVersion: "",
Protocol: listener.Properties.Protocol,
LoadDistribution: "",
FrontendPort: fpp.Properties.Port,
BackendPort: backendPort,
ClientIdleTimeout: 0,
EnableFloatingIP: false,
EnableTcpReset: false,
rules: u.Properties.PathRules,
}
}
func (self *SLoadbalancer) getNetworkLBListeners() ([]cloudprovider.ICloudLoadbalancerListener, error) {
lbls := []cloudprovider.ICloudLoadbalancerListener{}
for i := range self.Properties.LoadBalancingRules {
u := self.Properties.LoadBalancingRules[i]
lbl := self.getNetworkLBListener(&u)
lbls = append(lbls, &lbl)
}
return lbls, nil
}
func (self *SLoadbalancer) getNetworkLBListener(u *LoadBalancingRule) SLoadBalancerListener {
fp := self.getFrontendIPConfiguration(u.Properties.FrontendIPConfiguration.ID)
backendGroup := self.getBackendAddressPool(u.Properties.BackendAddressPool.ID)
healthcheck := self.getProbe(u.Properties.Probe.ID)
return SLoadBalancerListener{
lb: self,
fp: fp,
backendGroup: backendGroup,
healthcheck: healthcheck,
Name: u.Name,
ID: u.ID,
ProvisioningState: u.Properties.ProvisioningState,
IPVersion: "",
Protocol: u.Properties.Protocol,
LoadDistribution: u.Properties.LoadDistribution,
FrontendPort: u.Properties.FrontendPort,
BackendPort: u.Properties.BackendPort,
ClientIdleTimeout: u.Properties.IdleTimeoutInMinutes * 60,
EnableFloatingIP: u.Properties.EnableFloatingIP,
EnableTcpReset: u.Properties.EnableTCPReset,
}
}
// 应用型LB HTTP 设置 + 后端池 = onecloud 后端服务器组
// 4层LB: loadBalancingRules(backendPort)+ 后端池 = onecloud 后端服务器组
func (self *SLoadbalancer) GetILoadBalancerBackendGroups() ([]cloudprovider.ICloudLoadbalancerBackendGroup, error) {
if self.lbbgs != nil {
return self.lbbgs, nil
}
lbls, err := self.GetILoadBalancerListeners()
if err != nil {
return nil, errors.Wrap(err, "GetILoadBalancerListeners")
}
bgIds := []string{}
ilbbgs := []cloudprovider.ICloudLoadbalancerBackendGroup{}
for i := range lbls {
lbl := lbls[i].(*SLoadBalancerListener)
if lbl.backendGroup == nil {
continue
}
bg := SLoadbalancerBackendGroup{
lb: self,
Pool: *lbl.backendGroup,
DefaultPort: lbl.BackendPort,
HttpSettings: lbl.backendSetting,
BackendIps: lbl.backendGroup.Properties.BackendIPConfigurations,
}
if !utils.IsInStringArray(bg.GetId(), bgIds) {
bgIds = append(bgIds, bg.GetId())
ilbbgs = append(ilbbgs, &bg)
}
// sync rules lbbg
if utils.IsInStringArray(lbl.GetListenerType(), []string{api.LB_LISTENER_TYPE_HTTP, api.LB_LISTENER_TYPE_HTTPS}) {
rules, err := lbl.GetILoadbalancerListenerRules()
if err != nil {
return nil, errors.Wrap(err, "GetILoadbalancerListenerRules")
}
for j := range rules {
rule := rules[j].(*SLoadbalancerListenerRule)
if rule.lbbg != nil && !utils.IsInStringArray(rule.lbbg.GetId(), bgIds) {
bgIds = append(bgIds, bg.GetId())
ilbbgs = append(ilbbgs, &bg)
}
}
}
}
self.lbbgs = ilbbgs
return ilbbgs, nil
}
func (self *SLoadbalancer) GetILoadBalancerBackendGroupById(groupId string) (cloudprovider.ICloudLoadbalancerBackendGroup, error) {
lbbgs, err := self.GetILoadBalancerBackendGroups()
if err != nil {
return nil, errors.Wrap(err, "GetILoadBalancerBackendGroups")
}
for i := range lbbgs {
if lbbgs[i].GetId() == groupId {
return lbbgs[i], nil
}
}
return nil, errors.Wrap(cloudprovider.ErrNotFound, "GetILoadBalancerBackendGroupById")
}
func (self *SLoadbalancer) CreateILoadBalancerBackendGroup(group *cloudprovider.SLoadbalancerBackendGroup) (cloudprovider.ICloudLoadbalancerBackendGroup, error) {
return nil, errors.Wrap(cloudprovider.ErrNotImplemented, "CreateILoadBalancerBackendGroup")
}
func (self *SLoadbalancer) CreateILoadBalancerListener(ctx context.Context, listener *cloudprovider.SLoadbalancerListener) (cloudprovider.ICloudLoadbalancerListener, error) {
return nil, errors.Wrap(cloudprovider.ErrNotImplemented, "CreateILoadBalancerListener")
}
func (self *SLoadbalancer) getNetworkLBListenerById(id string) (cloudprovider.ICloudLoadbalancerListener, error) {
for i := range self.Properties.LoadBalancingRules {
u := self.Properties.LoadBalancingRules[i]
if u.ID == id {
lbl := self.getNetworkLBListener(&u)
return &lbl, nil
}
}
return nil, errors.Wrap(cloudprovider.ErrNotFound, "getNetworkLBListenerById")
}
func (self *SLoadbalancer) getAppLBListenerById(id string) (cloudprovider.ICloudLoadbalancerListener, error) {
for i := range self.Properties.URLPathMaps {
u := self.Properties.URLPathMaps[i]
if u.ID == id {
return self.getAppLBListener(&u), nil
}
}
return nil, errors.Wrap(cloudprovider.ErrNotFound, "getAppLBListenerById")
}
func (self *SLoadbalancer) GetILoadBalancerListenerById(listenerId string) (cloudprovider.ICloudLoadbalancerListener, error) {
if self.Type == "Microsoft.Network/applicationGateways" {
return self.getAppLBListenerById(listenerId)
} else {
return self.getNetworkLBListenerById(listenerId)
}
}
func (self *SLoadbalancer) GetILoadBalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) {
icerts := []cloudprovider.ICloudLoadbalancerCertificate{}
ssl := self.Properties.SSLCertificates
for i := range ssl {
s := ssl[i]
cert := SLoadbalancerCert{
lb: self,
Name: s.Name,
ID: s.ID,
PublicKey: s.Properties.PublicCertData,
}
icerts = append(icerts, &cert)
}
return icerts, nil
}
func (self *SLoadbalancer) GetILoadBalancerCertificateById(certId string) (cloudprovider.ICloudLoadbalancerCertificate, error) {
ssl := self.Properties.SSLCertificates
for i := range ssl {
s := ssl[i]
if s.ID == certId {
return &SLoadbalancerCert{
lb: self,
Name: s.Name,
ID: s.ID,
PublicKey: s.Properties.PublicCertData,
}, nil
}
}
return nil, errors.Wrap(cloudprovider.ErrNotFound, "GetILoadBalancerCertificateById")
}
+353
View File
@@ -0,0 +1,353 @@
package azure
type SLoadbalancerProperties struct {
Sku Sku `json:"sku"`
ProvisioningState string `json:"provisioningState"`
OperationalState string `json:"operationalState"`
ResourceGUID string `json:"resourceGuid"`
GatewayIPConfigurations []GatewayIPConfiguration `json:"gatewayIPConfigurations"`
SSLCertificates []SSLCertificate `json:"sslCertificates"`
FrontendIPConfigurations []FrontendIPConfiguration `json:"frontendIPConfigurations"`
FrontendPorts []FrontendPort `json:"frontendPorts"`
BackendAddressPools []BackendAddressPool `json:"backendAddressPools"`
BackendHTTPSettingsCollection []BackendHTTPSettingsCollection `json:"backendHttpSettingsCollection"`
LoadBalancingRules []LoadBalancingRule `json:"loadBalancingRules"`
Probes []Probe `json:"probes"`
InboundNatRules []InboundNatRule `json:"inboundNatRules"`
HTTPListeners []HTTPListener `json:"httpListeners"`
URLPathMaps []URLPathMap `json:"urlPathMaps"`
RequestRoutingRules []RequestRoutingRule `json:"requestRoutingRules"`
RedirectConfigurations []RedirectConfiguration `json:"redirectConfigurations"`
WebApplicationFirewallConfiguration WebApplicationFirewallConfiguration `json:"webApplicationFirewallConfiguration"`
EnableHttp2 bool `json:"enableHttp2"`
}
type BackendAddressPool struct {
Name string `json:"name"`
ID string `json:"id"`
Etag string `json:"etag"`
Properties BackendAddressPoolProperties `json:"properties"`
Type string `json:"type"`
}
type BackendAddressPoolProperties struct {
ProvisioningState string `json:"provisioningState"`
LoadBalancingRules []Subnet `json:"loadBalancingRules"`
BackendIPConfigurations []BackendIPConfiguration `json:"backendIPConfigurations"`
// loadBalancerBackendAddresses
}
type BackendIPConfiguration struct {
ID string `json:"id"`
}
type RedirectConfiguration struct {
Name string `json:"name"`
ID string `json:"id"`
Etag string `json:"etag"`
Properties RedirectConfigurationProperties `json:"properties"`
Type string `json:"type"`
}
type RedirectConfigurationProperties struct {
ProvisioningState string `json:"provisioningState"`
RedirectType string `json:"redirectType"`
TargetUrl string `json:"targetUrl"`
TargetListener PublicIPAddressElement `json:"targetListener"`
IncludePath bool `json:"includePath"`
IncludeQueryString bool `json:"includeQueryString"`
URLPathMaps []PublicIPAddressElement `json:"urlPathMaps,omitempty"`
PathRules []PublicIPAddressElement `json:"pathRules,omitempty"`
}
type WebApplicationFirewallConfiguration struct {
Enabled bool `json:"enabled"`
FirewallMode string `json:"firewallMode"`
RuleSetType string `json:"ruleSetType"`
RuleSetVersion string `json:"ruleSetVersion"`
DisabledRuleGroups []interface{} `json:"disabledRuleGroups"`
}
type URLPathMap struct {
Name string `json:"name"`
ID string `json:"id"`
Etag string `json:"etag"`
Properties URLPathMapProperties `json:"properties"`
Type string `json:"type"`
}
type URLPathMapProperties struct {
ProvisioningState string `json:"provisioningState"`
DefaultBackendAddressPool *PublicIPAddressElement `json:"defaultBackendAddressPool,omitempty"`
DefaultBackendHTTPSettings *PublicIPAddressElement `json:"defaultBackendHttpSettings,omitempty"`
PathRules []PathRule `json:"pathRules"`
RequestRoutingRules []PublicIPAddressElement `json:"requestRoutingRules"`
DefaultRedirectConfiguration *PublicIPAddressElement `json:"defaultRedirectConfiguration,omitempty"`
}
type PublicIPAddressElement struct {
ID string `json:"id"`
}
type PathRule struct {
Name string `json:"name"`
ID string `json:"id"`
Etag string `json:"etag"`
Properties PathRuleProperties `json:"properties"`
Type string `json:"type"`
}
type PathRuleProperties struct {
ProvisioningState string `json:"provisioningState"`
Paths []string `json:"paths"`
BackendAddressPool *PublicIPAddressElement `json:"backendAddressPool,omitempty"`
BackendHTTPSettings *PublicIPAddressElement `json:"backendHttpSettings,omitempty"`
RedirectConfiguration *PublicIPAddressElement `json:"redirectConfiguration,omitempty"`
}
type BackendAddress struct {
IPAddress string `json:"ipAddress"`
}
type BackendHTTPSettingsCollection struct {
Name string `json:"name"`
ID string `json:"id"`
Properties BackendHTTPSettingsCollectionProperties `json:"properties"`
}
type BackendHTTPSettingsCollectionProperties struct {
Port int `json:"port"`
Protocol string `json:"protocol"`
Probe *ProbeId `json:"probe"`
ConnectionDraining ConnectionDraining `json:"connectionDraining"`
CookieBasedAffinity string `json:"cookieBasedAffinity"`
AffinityCookieName string `json:"affinityCookieName"`
HostName string `json:"hostName"`
RequestTimeout int `json:"requestTimeout"`
}
type ConnectionDraining struct {
Enabled bool `json:"enabled"`
DrainTimeoutInSEC string `json:"drainTimeoutInSec"`
}
type ProbeId struct {
ID string `json:"id"`
}
type FrontendPort struct {
Name string `json:"name"`
ID string `json:"id"`
Properties FrontendPortProperties `json:"properties"`
}
type FrontendPortProperties struct {
Port int `json:"port"`
}
type GatewayIPConfiguration struct {
Name string `json:"name"`
ID string `json:"id"`
Properties GatewayIPConfigurationProperties `json:"properties"`
}
type GatewayIPConfigurationProperties struct {
Subnet PublicIPAddress `json:"subnet"`
}
type RequestRoutingRule struct {
Name string `json:"name"`
ID string `json:"id"`
Properties RequestRoutingRuleProperties `json:"properties"`
}
type RequestRoutingRuleProperties struct {
RuleType string `json:"ruleType"`
HTTPListener PublicIPAddress `json:"httpListener"`
BackendAddressPool PublicIPAddress `json:"backendAddressPool"`
BackendHTTPSettings PublicIPAddress `json:"backendHttpSettings"`
}
type SSLCertificate struct {
Name string `json:"name"`
ID string `json:"id"`
Properties SSLCertificateProperties `json:"properties"`
}
type SSLCertificateProperties struct {
ProvisioningState string `json:"provisioningState"`
PublicCertData string `json:"public_cert_data"`
Data string `json:"data"`
Password string `json:"password"`
}
type Sku struct {
Name string `json:"name"`
Tier string `json:"tier"`
Capacity string `json:"capacity"`
}
type Subnet struct {
ID string `json:"id"`
}
type FrontendIPConfiguration struct {
Name string `json:"name"`
ID string `json:"id"`
Etag string `json:"etag"`
Type string `json:"type"`
Zones []string `json:"zones"`
Properties FrontendIPConfigurationProperties `json:"properties"`
}
type FrontendIPConfigurationProperties struct {
ProvisioningState string `json:"provisioningState"`
PrivateIPAddress string `json:"privateIPAddress"`
PublicIPAddress *PublicIPAddress `json:"publicIPAddress,omitempty"`
PrivateIPAllocationMethod string `json:"privateIPAllocationMethod"`
PrivateIPAddressVersion string `json:"privateIPAddressVersion"`
Subnet Subnet `json:"subnet"`
LoadBalancingRules []Subnet `json:"loadBalancingRules"`
InboundNatRules []Subnet `json:"inboundNatRules"`
}
type InboundNatRule struct {
Name string `json:"name"`
ID string `json:"id"`
Etag string `json:"etag"`
Type string `json:"type"`
Properties InboundNatRuleProperties `json:"properties"`
}
type InboundNatRuleProperties struct {
ProvisioningState string `json:"provisioningState"`
FrontendIPConfiguration Subnet `json:"frontendIPConfiguration"`
FrontendPort int64 `json:"frontendPort"`
BackendPort int64 `json:"backendPort"`
EnableFloatingIP bool `json:"enableFloatingIP"`
IdleTimeoutInMinutes int64 `json:"idleTimeoutInMinutes"`
Protocol string `json:"protocol"`
EnableTCPReset bool `json:"enableTcpReset"`
}
type SLoadbalancerSku struct {
Name string `json:"name"`
}
type Probe struct {
lb *SLoadbalancer
Name string `json:"name"`
ID string `json:"id"`
Etag string `json:"etag"`
Type string `json:"type"`
Properties ProbeProperties `json:"properties"`
}
type ProbeProperties struct {
// tcp/udp/http/https
ProvisioningState string `json:"provisioningState"`
Protocol string `json:"protocol"`
Port int `json:"port"`
RequestPath string `json:"requestPath"`
IntervalInSeconds int `json:"intervalInSeconds"`
NumberOfProbes int `json:"numberOfProbes"`
// http/ https only
Host string `json:"host"`
Path string `json:"path"`
Interval int `json:"interval"`
Timeout int `json:"timeout"`
UnhealthyThreshold int `json:"unhealthyThreshold"`
PickHostNameFromBackendHTTPSettings bool `json:"pickHostNameFromBackendHttpSettings"`
MinServers int `json:"minServers"`
Match Match `json:"match"`
LoadBalancingRules []Subnet `json:"loadBalancingRules"`
}
type Match struct {
Body string `json:"body"`
StatusCodes []string `json:"statusCodes"`
}
type LoadBalancingRule struct {
Name string `json:"name"`
ID string `json:"id"`
Etag string `json:"etag"`
Type string `json:"type"`
Properties LoadBalancingRuleProperties `json:"properties"`
}
type LoadBalancingRuleProperties struct {
ProvisioningState string `json:"provisioningState"`
FrontendIPConfiguration Subnet `json:"frontendIPConfiguration"`
FrontendPort int `json:"frontendPort"`
BackendPort int `json:"backendPort"`
EnableFloatingIP bool `json:"enableFloatingIP"`
IdleTimeoutInMinutes int `json:"idleTimeoutInMinutes"`
Protocol string `json:"protocol"`
EnableTCPReset bool `json:"enableTcpReset"`
LoadDistribution string `json:"loadDistribution"`
BackendAddressPool Subnet `json:"backendAddressPool"`
Probe Subnet `json:"probe"`
}
type HTTPListener struct {
Name string `json:"name"`
ID string `json:"id"`
Properties HTTPListenerProperties `json:"properties"`
}
type HTTPListenerProperties struct {
FrontendIPConfiguration PublicIPAddress `json:"frontendIPConfiguration"`
FrontendPort PublicIPAddress `json:"frontendPort"`
HostName string `json:"hostName"`
Protocol string `json:"protocol"`
SSLCertificate PublicIPAddress `json:"sslCertificate"`
RequestRoutingRules []Subnet `json:"requestRoutingRules"`
RequireServerNameIndication bool `json:"requireServerNameIndication"`
}
type ContentProperties struct {
ProvisioningState string `json:"provisioningState"`
ResourceGUID string `json:"resourceGuid"`
IPConfigurations []NetworkInterfaceIPConfiguration `json:"ipConfigurations"`
DNSSettings DNSSettings `json:"dnsSettings"`
MACAddress string `json:"macAddress"`
EnableAcceleratedNetworking bool `json:"enableAcceleratedNetworking"`
EnableIPForwarding bool `json:"enableIPForwarding"`
NetworkSecurityGroup NetworkSecurityGroup `json:"networkSecurityGroup"`
Primary bool `json:"primary"`
VirtualMachine NetworkSecurityGroup `json:"virtualMachine"`
HostedWorkloads []interface{} `json:"hostedWorkloads"`
TapConfigurations []interface{} `json:"tapConfigurations"`
}
type DNSSettings struct {
DNSServers []interface{} `json:"dnsServers"`
AppliedDNSServers []interface{} `json:"appliedDnsServers"`
InternalDomainNameSuffix string `json:"internalDomainNameSuffix"`
}
type NetworkInterfaceIPConfiguration struct {
Name string `json:"name"`
ID string `json:"id"`
Etag string `json:"etag"`
Type string `json:"type"`
Properties IPConfigurationProperties `json:"properties"`
}
type IPConfigurationProperties struct {
ProvisioningState string `json:"provisioningState"`
PrivateIPAddress string `json:"privateIPAddress"`
PrivateIPAllocationMethod string `json:"privateIPAllocationMethod"`
PublicIPAddress NetworkSecurityGroup `json:"publicIPAddress"`
Subnet NetworkSecurityGroup `json:"subnet"`
Primary bool `json:"primary"`
PrivateIPAddressVersion string `json:"privateIPAddressVersion"`
LoadBalancerBackendAddressPools []NetworkSecurityGroup `json:"loadBalancerBackendAddressPools"`
LoadBalancerInboundNatRules []NetworkSecurityGroup `json:"loadBalancerInboundNatRules"`
}
type NetworkSecurityGroup struct {
ID string `json:"id"`
}
@@ -0,0 +1,78 @@
package azure
import (
"context"
"strconv"
"github.com/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
)
type SLoadbalancerBackend struct {
multicloud.SResourceBase
lbbg *SLoadbalancerBackendGroup
// networkInterfaces 通过接口地址反查虚拟机地址
Name string `json:"name"`
ID string `json:"id"`
Type string `json:"type"`
BackendPort int
}
func (self *SLoadbalancerBackend) GetId() string {
return self.ID + "::" + strconv.Itoa(self.BackendPort)
}
func (self *SLoadbalancerBackend) GetName() string {
return self.Name
}
func (self *SLoadbalancerBackend) GetGlobalId() string {
return self.GetId()
}
func (self *SLoadbalancerBackend) GetStatus() string {
return api.LB_STATUS_ENABLED
}
func (self *SLoadbalancerBackend) GetSysTags() map[string]string {
return nil
}
func (self *SLoadbalancerBackend) GetTags() (map[string]string, error) {
return nil, nil
}
func (self *SLoadbalancerBackend) SetTags(tags map[string]string, replace bool) error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "SetTags")
}
func (self *SLoadbalancerBackend) GetProjectId() string {
return getResourceGroup(self.ID)
}
func (self *SLoadbalancerBackend) GetWeight() int {
return 0
}
func (self *SLoadbalancerBackend) GetPort() int {
return self.BackendPort
}
func (self *SLoadbalancerBackend) GetBackendType() string {
return api.LB_BACKEND_GUEST
}
func (self *SLoadbalancerBackend) GetBackendRole() string {
return api.LB_BACKEND_ROLE_DEFAULT
}
func (self *SLoadbalancerBackend) GetBackendId() string {
return self.ID
}
func (self *SLoadbalancerBackend) SyncConf(ctx context.Context, port, weight int) error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "SyncConf")
}
@@ -0,0 +1,187 @@
package azure
import (
"context"
"strconv"
"strings"
"github.com/pkg/errors"
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
)
// todo: 虚拟机规模集不支持
// 注: 因为与onecloud后端服务器组存在配置差异,不支持同步未关联的后端服务器组
// 应用型LB HTTP 设置 + 后端池 = onecloud 后端服务器组
// 4层LB: loadBalancingRules(backendPort)+ 后端池 = onecloud 后端服务器组
type SLoadbalancerBackendGroup struct {
lb *SLoadbalancer
lbbs []cloudprovider.ICloudLoadbalancerBackend
Pool BackendAddressPool
DefaultPort int
HttpSettings *BackendHTTPSettingsCollection
BackendIps []BackendIPConfiguration
}
func (self *SLoadbalancerBackendGroup) GetId() string {
return self.Pool.ID + "::" + strconv.Itoa(self.DefaultPort)
}
func (self *SLoadbalancerBackendGroup) GetName() string {
if self.HttpSettings != nil {
return self.Pool.Name + "::" + self.HttpSettings.Name
}
return self.Pool.Name + "::" + strconv.Itoa(self.DefaultPort)
}
func (self *SLoadbalancerBackendGroup) GetGlobalId() string {
return self.GetId()
}
func (self *SLoadbalancerBackendGroup) GetStatus() string {
switch self.Pool.Properties.ProvisioningState {
case "Succeeded":
return api.LB_STATUS_ENABLED
default:
return api.LB_STATUS_UNKNOWN
}
}
func (self *SLoadbalancerBackendGroup) Refresh() error {
lbbg, err := self.lb.GetILoadBalancerBackendGroupById(self.GetId())
if err != nil {
return errors.Wrap(err, "GetILoadBalancerBackendGroupById")
}
err = jsonutils.Update(self, lbbg)
if err != nil {
return errors.Wrap(err, "refresh.Update")
}
self.lbbs = nil
return nil
}
func (self *SLoadbalancerBackendGroup) IsEmulated() bool {
return true
}
func (self *SLoadbalancerBackendGroup) GetSysTags() map[string]string {
return nil
}
func (self *SLoadbalancerBackendGroup) GetTags() (map[string]string, error) {
return map[string]string{}, nil
}
func (self *SLoadbalancerBackendGroup) SetTags(tags map[string]string, replace bool) error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "SetTags")
}
func (self *SLoadbalancerBackendGroup) GetProjectId() string {
return getResourceGroup(self.GetId())
}
func (self *SLoadbalancerBackendGroup) IsDefault() bool {
return false
}
func (self *SLoadbalancerBackendGroup) GetType() string {
return api.LB_BACKENDGROUP_TYPE_NORMAL
}
func (self *SLoadbalancerBackendGroup) GetLoadbalancerId() string {
return self.lb.GetId()
}
func (self *SLoadbalancerBackendGroup) GetILoadbalancerBackends() ([]cloudprovider.ICloudLoadbalancerBackend, error) {
if self.lbbs != nil {
return self.lbbs, nil
}
var ret []cloudprovider.ICloudLoadbalancerBackend
ips := self.Pool.Properties.BackendIPConfigurations
for i := range ips {
ip := ips[i]
nic, err := self.lb.region.GetNetworkInterface(strings.Split(ip.ID, "/ipConfigurations")[0])
if err != nil {
return nil, errors.Wrap(err, "GetNetworkInterface")
}
if len(nic.Properties.VirtualMachine.ID) == 0 {
continue
}
name := nic.Properties.VirtualMachine.Name
vid := nic.Properties.VirtualMachine.ID
if len(name) == 0 && len(vid) > 0 {
segs := strings.Split(vid, "/virtualMachines/")
name = segs[len(segs)-1]
}
bg := SLoadbalancerBackend{
SResourceBase: multicloud.SResourceBase{},
lbbg: self,
Name: name,
ID: vid,
Type: api.LB_BACKEND_GUEST,
BackendPort: self.DefaultPort,
}
ret = append(ret, &bg)
}
self.lbbs = ret
return ret, nil
}
func (self *SLoadbalancerBackendGroup) GetILoadbalancerBackendById(backendId string) (cloudprovider.ICloudLoadbalancerBackend, error) {
lbbs, err := self.GetILoadbalancerBackends()
if err != nil {
return nil, errors.Wrap(err, "GetILoadbalancerBackends")
}
for i := range lbbs {
if lbbs[i].GetId() == backendId {
return lbbs[i], nil
}
}
return nil, errors.Wrap(cloudprovider.ErrNotFound, "GetILoadbalancerBackendById")
}
func (self *SLoadbalancerBackendGroup) GetProtocolType() string {
return ""
}
func (self *SLoadbalancerBackendGroup) GetScheduler() string {
return ""
}
func (self *SLoadbalancerBackendGroup) GetHealthCheck() (*cloudprovider.SLoadbalancerHealthCheck, error) {
return nil, nil
}
func (self *SLoadbalancerBackendGroup) GetStickySession() (*cloudprovider.SLoadbalancerStickySession, error) {
return nil, nil
}
func (self *SLoadbalancerBackendGroup) AddBackendServer(serverId string, weight int, port int) (cloudprovider.ICloudLoadbalancerBackend, error) {
return nil, errors.Wrap(cloudprovider.ErrNotImplemented, "AddBackendServer")
}
func (self *SLoadbalancerBackendGroup) RemoveBackendServer(serverId string, weight int, port int) error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "RemoveBackendServer")
}
func (self *SLoadbalancerBackendGroup) Delete(ctx context.Context) error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "Delete")
}
func (self *SLoadbalancerBackendGroup) Sync(ctx context.Context, group *cloudprovider.SLoadbalancerBackendGroup) error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "Sync")
}
+167
View File
@@ -0,0 +1,167 @@
package azure
import (
"bytes"
"crypto/sha1"
"crypto/x509"
"encoding/pem"
"fmt"
"strings"
"time"
"github.com/pkg/errors"
"go.uber.org/zap/buffer"
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SLoadbalancerCert struct {
lb *SLoadbalancer
cert *x509.Certificate
Name string `json:"name"`
ID string `json:"id"`
PublicKey string `json:"public_key"`
}
func (self *SLoadbalancerCert) GetId() string {
return self.ID
}
func (self *SLoadbalancerCert) GetName() string {
return self.Name
}
func (self *SLoadbalancerCert) GetGlobalId() string {
return self.GetId()
}
func (self *SLoadbalancerCert) GetStatus() string {
return api.LB_STATUS_ENABLED
}
func (self *SLoadbalancerCert) Refresh() error {
cert, err := self.lb.GetILoadBalancerCertificateById(self.GetId())
if err != nil {
return errors.Wrap(err, "GetILoadBalancerCertificateById")
}
err = jsonutils.Update(self, cert)
if err != nil {
return errors.Wrap(err, "Update")
}
return nil
}
func (self *SLoadbalancerCert) IsEmulated() bool {
return false
}
func (self *SLoadbalancerCert) GetSysTags() map[string]string {
return nil
}
func (self *SLoadbalancerCert) GetTags() (map[string]string, error) {
return nil, nil
}
func (self *SLoadbalancerCert) SetTags(tags map[string]string, replace bool) error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "SetTags")
}
func (self *SLoadbalancerCert) GetProjectId() string {
return getResourceGroup(self.GetId())
}
func (self *SLoadbalancerCert) Sync(name, privateKey, publickKey string) error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "Sync")
}
func (self *SLoadbalancerCert) Delete() error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "Delete")
}
func (self *SLoadbalancerCert) ParsePublicKey() (*x509.Certificate, error) {
if self.cert != nil {
return self.cert, nil
}
publicKey := self.GetPublickKey()
if len(publicKey) == 0 {
return nil, fmt.Errorf("SElbCertificate ParsePublicKey public key is empty")
}
block, _ := pem.Decode([]byte(publicKey))
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, errors.Wrap(err, "ParseCertificate")
}
self.cert = cert
return cert, nil
}
func (self *SLoadbalancerCert) GetCommonName() string {
cert, err := self.ParsePublicKey()
if err != nil {
return ""
}
return cert.Issuer.CommonName
}
func (self *SLoadbalancerCert) GetSubjectAlternativeNames() string {
_, err := self.ParsePublicKey()
if err != nil {
return ""
}
return ""
}
func (self *SLoadbalancerCert) GetFingerprint() string {
publicKey := self.GetPublickKey()
if len(publicKey) == 0 {
return ""
}
_fp := sha1.Sum([]byte(publicKey))
fp := fmt.Sprintf("sha1:% x", _fp)
return strings.Replace(fp, " ", ":", -1)
}
func (self *SLoadbalancerCert) GetExpireTime() time.Time {
cert, err := self.ParsePublicKey()
if err != nil {
return time.Time{}
}
return cert.NotAfter
}
func (self *SLoadbalancerCert) GetPublickKey() string {
if len(self.PublicKey) > 0 {
var pk buffer.Buffer
pk.AppendString("-----BEGIN CERTIFICATE-----\r\n")
content := bytes.NewBufferString(self.PublicKey)
for {
l := content.Next(64)
if len(l) == 64 {
pk.AppendString(fmt.Sprintf("%s\r\n", l))
} else {
pk.AppendString(fmt.Sprintf("%s\r\n", l))
break
}
}
pk.AppendString("-----END CERTIFICATE-----")
return pk.String()
}
return ""
}
func (self *SLoadbalancerCert) GetPrivateKey() string {
return ""
}
@@ -0,0 +1,569 @@
package azure
import (
"context"
"net/url"
"regexp"
"strconv"
"strings"
"yunion.io/x/log"
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
"yunion.io/x/pkg/errors"
)
// todo: 目前不支持 入站 NAT 规则
// todo: HTTP 设置(端口+协议,其余信息丢弃) + 后端池 = onecloud 路径的路由 的 onecloud 后端服务器组
/*
应用型LB urlPathMapsdefaultBackendAddressPool+defaultBackendHttpSettings+requestRoutingRules+httpListeners= Onecloud监听器
4层LB: loadBalancingRules(前端) = Onecloud监听器
*/
type SLoadBalancerListener struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
lb *SLoadbalancer
lbrs []cloudprovider.ICloudLoadbalancerListenerRule
/*
IPVersion string
FrontendIP string // 前端IP
FrontendIPId string // 前端IP ID
*/
fp *FrontendIPConfiguration
/*
Protocol string // 监听协议
HostName string // 监听器 监听域名
FrontendPort int // 前端端口
*/
listener *HTTPListener
/*
Protocol string // 后端协议
BackendPort int // 后端端口
IdleTimeoutInMinutes int // 空闲超时(分钟)
LoadDistribution string // 会话保持方法SourceIP|SourceIPProtocol
CookieBasedAffinity string // cookies 关联
CookieName string // cookie 名称
EnabledConnectionDraining bool // 排出超时这应用于通过 API 调用从后端池明确删除的后端实例,以及运行状况探测报告的运行不正常的实例。
ConnectionDrainingSec int // 排出超时时长(秒)
RequestTimeout int // 请求超时时间(秒)
probe // 健康检查
*/
backendSetting *BackendHTTPSettingsCollection
//
backendGroup *BackendAddressPool
/*
redirectType string // 重定向类型
targetListener // 重定向到监听
*/
redirect *RedirectConfiguration
/*
"protocol": "Http",
"host": "baidu.com",
"path": "/test",
"interval": 30,
"timeout": 30,
"unhealthyThreshold": 3,
"pickHostNameFromBackendHttpSettings": false,
"minServers": 0,
"match": {
"body": "500",
"statusCodes": [
"200-399"
]
},
*/
healthcheck *Probe
Name string
ID string
ProvisioningState string
IPVersion string
Protocol string // 监听协议
LoadDistribution string // 调度算法
FrontendPort int // 前端端口
BackendPort int // 后端端口
ClientIdleTimeout int // 客户端连接超时
EnableFloatingIP bool // 浮动 IP
EnableTcpReset bool
rules []PathRule
}
func (self *SLoadBalancerListener) GetId() string {
return self.ID
}
func (self *SLoadBalancerListener) GetName() string {
return self.Name
}
func (self *SLoadBalancerListener) GetGlobalId() string {
return self.GetId()
}
func (self *SLoadBalancerListener) GetStatus() string {
switch self.ProvisioningState {
case "Succeeded":
return api.LB_STATUS_ENABLED
case "Failed":
return api.LB_STATUS_DISABLED
default:
return api.LB_STATUS_UNKNOWN
}
}
func (self *SLoadBalancerListener) Refresh() error {
lbl, err := self.lb.GetILoadBalancerListenerById(self.GetId())
if err != nil {
return errors.Wrap(err, "GetILoadBalancerListenerById")
}
err = jsonutils.Update(self, lbl)
if err != nil {
return errors.Wrap(err, "refresh.Update")
}
self.lbrs = nil
return nil
}
func (self *SLoadBalancerListener) IsEmulated() bool {
return false
}
func (self *SLoadBalancerListener) GetSysTags() map[string]string {
return nil
}
func (self *SLoadBalancerListener) GetTags() (map[string]string, error) {
return nil, nil
}
func (self *SLoadBalancerListener) SetTags(tags map[string]string, replace bool) error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "SetTags")
}
func (self *SLoadBalancerListener) GetProjectId() string {
return getResourceGroup(self.GetId())
}
func (self *SLoadBalancerListener) GetListenerType() string {
switch strings.ToLower(self.Protocol) {
case "tcp":
return api.LB_LISTENER_TYPE_TCP
case "udp":
return api.LB_LISTENER_TYPE_UDP
case "http":
return api.LB_LISTENER_TYPE_HTTP
case "https":
return api.LB_LISTENER_TYPE_HTTPS
default:
return ""
}
}
func (self *SLoadBalancerListener) GetListenerPort() int {
return int(self.FrontendPort)
}
func (self *SLoadBalancerListener) GetScheduler() string {
switch self.LoadDistribution {
case "SourceIPProtocol", "SourceIP":
return api.LB_SCHEDULER_SCH
default:
return ""
}
}
func (self *SLoadBalancerListener) GetAclStatus() string {
return api.LB_BOOL_OFF
}
func (self *SLoadBalancerListener) GetAclType() string {
return ""
}
func (self *SLoadBalancerListener) GetAclId() string {
return ""
}
func (self *SLoadBalancerListener) GetEgressMbps() int {
return 0
}
func (self *SLoadBalancerListener) GetHealthCheck() string {
// if self.probe != nil
if self.healthcheck != nil {
return api.LB_BOOL_ON
}
return api.LB_BOOL_OFF
}
func (self *SLoadBalancerListener) GetHealthCheckType() string {
if self.healthcheck == nil {
return ""
}
switch strings.ToLower(self.healthcheck.Properties.Protocol) {
case "tcp":
return api.LB_HEALTH_CHECK_TCP
case "udp":
return api.LB_HEALTH_CHECK_UDP
case "http":
return api.LB_HEALTH_CHECK_HTTP
case "https":
return api.LB_HEALTH_CHECK_HTTPS
default:
return ""
}
}
func (self *SLoadBalancerListener) GetHealthCheckTimeout() int {
if self.healthcheck == nil {
return 0
}
switch self.GetHealthCheckType() {
case api.LB_HEALTH_CHECK_HTTP, api.LB_HEALTH_CHECK_HTTPS:
return self.healthcheck.Properties.Timeout
}
return self.healthcheck.Properties.IntervalInSeconds
}
func (self *SLoadBalancerListener) GetHealthCheckInterval() int {
if self.healthcheck == nil {
return 0
}
switch self.GetHealthCheckType() {
case api.LB_HEALTH_CHECK_HTTP, api.LB_HEALTH_CHECK_HTTPS:
return self.healthcheck.Properties.Interval
}
return self.healthcheck.Properties.IntervalInSeconds
}
func (self *SLoadBalancerListener) GetHealthCheckRise() int {
return 0
}
func (self *SLoadBalancerListener) GetHealthCheckFail() int {
if self.healthcheck == nil {
return 0
}
switch self.GetHealthCheckType() {
case api.LB_HEALTH_CHECK_HTTP, api.LB_HEALTH_CHECK_HTTPS:
return self.healthcheck.Properties.UnhealthyThreshold
}
return self.healthcheck.Properties.IntervalInSeconds
}
func (self *SLoadBalancerListener) GetHealthCheckReq() string {
return ""
}
func (self *SLoadBalancerListener) GetHealthCheckExp() string {
return ""
}
func (self *SLoadBalancerListener) GetBackendGroupId() string {
if self.backendGroup != nil {
return self.backendGroup.ID + "::" + strconv.Itoa(self.BackendPort)
}
return ""
}
func (self *SLoadBalancerListener) GetBackendServerPort() int {
return self.BackendPort
}
func (self *SLoadBalancerListener) GetHealthCheckDomain() string {
if self.healthcheck == nil {
return ""
}
switch self.GetHealthCheckType() {
case api.LB_HEALTH_CHECK_HTTP, api.LB_HEALTH_CHECK_HTTPS:
return self.healthcheck.Properties.Host
}
return ""
}
func (self *SLoadBalancerListener) GetHealthCheckURI() string {
if self.healthcheck == nil {
return ""
}
switch self.GetHealthCheckType() {
case api.LB_HEALTH_CHECK_HTTP, api.LB_HEALTH_CHECK_HTTPS:
return self.healthcheck.Properties.Path
}
return ""
}
/*
todo: 和onecloud code不兼容?
与此处输入的 HTTP 状态代码或代码范围相匹配的响应将被视为成功。请输入逗号分隔的代码列表(例如 200, 201)或者输入一个代码范围(例如 220-226)
*/
func (self *SLoadBalancerListener) GetHealthCheckCode() string {
return ""
}
func (self *SLoadBalancerListener) CreateILoadBalancerListenerRule(rule *cloudprovider.SLoadbalancerListenerRule) (cloudprovider.ICloudLoadbalancerListenerRule, error) {
return nil, errors.Wrap(cloudprovider.ErrNotImplemented, "CreateILoadBalancerListenerRule")
}
func (self *SLoadBalancerListener) GetILoadBalancerListenerRuleById(ruleId string) (cloudprovider.ICloudLoadbalancerListenerRule, error) {
lbrs, err := self.GetILoadbalancerListenerRules()
if err != nil {
return nil, errors.Wrap(err, "GetILoadbalancerListenerRules")
}
for i := range lbrs {
if lbrs[i].GetId() == ruleId {
return lbrs[i], nil
}
}
return nil, errors.Wrap(err, "GetILoadBalancerListenerRuleById")
}
func (self *SLoadBalancerListener) GetILoadbalancerListenerRules() ([]cloudprovider.ICloudLoadbalancerListenerRule, error) {
if self.lbrs != nil {
return self.lbrs, nil
}
irules := []cloudprovider.ICloudLoadbalancerListenerRule{}
for i := range self.rules {
r := self.rules[i]
var redirect *RedirectConfiguration
var lbbg *SLoadbalancerBackendGroup
if r.Properties.RedirectConfiguration != nil {
redirect = self.lb.getRedirectConfiguration(r.Properties.RedirectConfiguration.ID)
} else {
if r.Properties.BackendAddressPool == nil || r.Properties.BackendHTTPSettings == nil {
continue
}
pool := self.lb.getBackendAddressPool(r.Properties.BackendAddressPool.ID)
if pool == nil {
log.Debugf("getBackendAddressPool %s not found", r.Properties.BackendAddressPool.ID)
continue
}
backsetting := self.lb.getBackendHTTPSettingsCollection(r.Properties.BackendHTTPSettings.ID)
if backsetting == nil {
log.Debugf("getBackendHTTPSettingsCollection %s not found", r.Properties.BackendHTTPSettings.ID)
continue
}
lbbg = &SLoadbalancerBackendGroup{
lb: self.lb,
Pool: *pool,
DefaultPort: backsetting.Properties.Port,
HttpSettings: backsetting,
BackendIps: pool.Properties.BackendIPConfigurations,
}
}
domain := ""
if self.listener != nil {
domain = self.listener.Properties.HostName
}
rule := SLoadbalancerListenerRule{
SResourceBase: multicloud.SResourceBase{},
listener: self,
lbbg: lbbg,
redirect: redirect,
Name: r.Name,
ID: r.ID,
Domain: domain,
Properties: r.Properties,
}
irules = append(irules, &rule)
}
return irules, nil
}
func (self *SLoadBalancerListener) GetStickySession() string {
if self.backendSetting == nil {
return api.LB_BOOL_OFF
}
if self.backendSetting.Properties.CookieBasedAffinity == "Enabled" {
return api.LB_BOOL_ON
} else {
return api.LB_BOOL_OFF
}
}
func (self *SLoadBalancerListener) GetStickySessionType() string {
if self.GetStickySession() == api.LB_BOOL_ON {
return api.LB_STICKY_SESSION_TYPE_INSERT
}
return ""
}
func (self *SLoadBalancerListener) GetStickySessionCookie() string {
if self.backendSetting == nil {
return ""
}
return self.backendSetting.Properties.AffinityCookieName
}
func (self *SLoadBalancerListener) GetStickySessionCookieTimeout() int {
if self.backendSetting == nil {
return 0
}
if self.backendSetting.Properties.ConnectionDraining.Enabled {
_sec := strings.TrimSpace(self.backendSetting.Properties.ConnectionDraining.DrainTimeoutInSEC)
sec, _ := strconv.ParseInt(_sec, 10, 64)
return int(sec)
}
return 0
}
func (self *SLoadBalancerListener) XForwardedForEnabled() bool {
return false
}
func (self *SLoadBalancerListener) GzipEnabled() bool {
return false
}
func (self *SLoadBalancerListener) GetCertificateId() string {
if self.listener != nil {
return self.listener.Properties.SSLCertificate.ID
}
return ""
}
func (self *SLoadBalancerListener) GetTLSCipherPolicy() string {
return ""
}
func (self *SLoadBalancerListener) HTTP2Enabled() bool {
return self.lb.Properties.EnableHttp2
}
func (self *SLoadBalancerListener) Start() error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "Start")
}
func (self *SLoadBalancerListener) Stop() error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "Stop")
}
func (self *SLoadBalancerListener) Sync(ctx context.Context, listener *cloudprovider.SLoadbalancerListener) error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "Sync")
}
func (self *SLoadBalancerListener) Delete(ctx context.Context) error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "Delete")
}
func (self *SLoadBalancerListener) GetRedirect() string {
if self.redirect != nil {
return api.LB_REDIRECT_RAW
}
return api.LB_REDIRECT_OFF
}
func (self *SLoadBalancerListener) GetRedirectCode() int64 {
if self.redirect == nil {
return 0
}
switch self.redirect.Properties.RedirectType {
case "Permanent":
return api.LB_REDIRECT_CODE_301
case "Found":
return api.LB_REDIRECT_CODE_302
case "Temporary", "SeeOther":
return api.LB_REDIRECT_CODE_307
default:
return 0
}
}
func (self *SLoadBalancerListener) getRedirectUrl() *url.URL {
if self.redirect == nil {
return nil
}
if len(self.redirect.Properties.TargetUrl) == 0 {
return nil
}
_url := self.redirect.Properties.TargetUrl
if matched, _ := regexp.MatchString("^\\w{0,5}://", _url); !matched {
_url = "http://" + _url
}
u, err := url.Parse(_url)
if err != nil {
log.Debugf("url Parse %s : %s", self.redirect.Properties.TargetUrl, err)
return nil
}
return u
}
func (self *SLoadBalancerListener) GetRedirectScheme() string {
u := self.getRedirectUrl()
if u == nil {
return ""
}
return strings.ToLower(u.Scheme)
}
func (self *SLoadBalancerListener) GetRedirectHost() string {
u := self.getRedirectUrl()
if u == nil {
if self.redirect != nil && len(self.redirect.Properties.TargetListener.ID) > 0 {
segs := strings.Split(self.redirect.Properties.TargetListener.ID, "/")
return segs[len(segs)-1]
}
return ""
}
return u.Host
}
func (self *SLoadBalancerListener) GetRedirectPath() string {
u := self.getRedirectUrl()
if u == nil {
return ""
}
return u.Path
}
func (self *SLoadBalancerListener) GetClientIdleTimeout() int {
return self.ClientIdleTimeout
}
func (self *SLoadBalancerListener) GetBackendConnectTimeout() int {
if self.backendSetting == nil {
return 0
}
return self.backendSetting.Properties.RequestTimeout
}
@@ -0,0 +1,178 @@
package azure
import (
"context"
"net/url"
"regexp"
"strings"
"yunion.io/x/log"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
"yunion.io/x/pkg/errors"
)
type SLoadbalancerListenerRule struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
listener *SLoadBalancerListener
lbbg *SLoadbalancerBackendGroup
redirect *RedirectConfiguration
// urlPathMaps -> pathRules
Name string `json:"name"`
ID string `json:"id"`
Domain string `json:"domain"`
Properties PathRuleProperties `json:"properties"`
}
func (self *SLoadbalancerListenerRule) GetId() string {
return self.ID
}
func (self *SLoadbalancerListenerRule) GetName() string {
return self.Name
}
func (self *SLoadbalancerListenerRule) GetGlobalId() string {
return self.GetId()
}
func (self *SLoadbalancerListenerRule) GetStatus() string {
switch self.Properties.ProvisioningState {
case "Succeeded":
return api.LB_STATUS_ENABLED
case "Failed":
return api.LB_STATUS_DISABLED
default:
return api.LB_STATUS_UNKNOWN
}
}
func (self *SLoadbalancerListenerRule) GetSysTags() map[string]string {
return nil
}
func (self *SLoadbalancerListenerRule) GetTags() (map[string]string, error) {
return nil, nil
}
func (self *SLoadbalancerListenerRule) SetTags(tags map[string]string, replace bool) error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "SetTags")
}
func (self *SLoadbalancerListenerRule) GetProjectId() string {
return getResourceGroup(self.GetId())
}
func (self *SLoadbalancerListenerRule) IsDefault() bool {
return false
}
func (self *SLoadbalancerListenerRule) GetDomain() string {
return self.Domain
}
func (self *SLoadbalancerListenerRule) GetPath() string {
if len(self.Properties.Paths) > 0 {
return self.Properties.Paths[0]
}
return ""
}
func (self *SLoadbalancerListenerRule) GetCondition() string {
return ""
}
func (self *SLoadbalancerListenerRule) GetBackendGroupId() string {
if self.lbbg != nil {
return self.lbbg.GetId()
}
return ""
}
func (self *SLoadbalancerListenerRule) Delete(ctx context.Context) error {
return errors.Wrap(cloudprovider.ErrNotImplemented, "Delete")
}
func (self *SLoadbalancerListenerRule) GetRedirect() string {
if self.redirect != nil {
return api.LB_REDIRECT_RAW
}
return api.LB_REDIRECT_OFF
}
func (self *SLoadbalancerListenerRule) GetRedirectCode() int64 {
if self.redirect == nil {
return 0
}
switch self.redirect.Properties.RedirectType {
case "Permanent":
return api.LB_REDIRECT_CODE_301
case "Found":
return api.LB_REDIRECT_CODE_302
case "Temporary", "SeeOther":
return api.LB_REDIRECT_CODE_307
default:
return 0
}
}
func (self *SLoadbalancerListenerRule) getRedirectUrl() *url.URL {
if self.redirect == nil {
return nil
}
if len(self.redirect.Properties.TargetUrl) == 0 {
return nil
}
_url := self.redirect.Properties.TargetUrl
if matched, _ := regexp.MatchString("^\\w{0,5}://", _url); !matched {
_url = "http://" + _url
}
u, err := url.Parse(_url)
if err != nil {
log.Debugf("url Parse %s : %s", self.redirect.Properties.TargetUrl, err)
return nil
}
return u
}
func (self *SLoadbalancerListenerRule) GetRedirectScheme() string {
u := self.getRedirectUrl()
if u == nil {
return ""
}
return strings.ToLower(u.Scheme)
}
func (self *SLoadbalancerListenerRule) GetRedirectHost() string {
u := self.getRedirectUrl()
if u == nil {
if self.redirect != nil && len(self.redirect.Properties.TargetListener.ID) > 0 {
segs := strings.Split(self.redirect.Properties.TargetListener.ID, "/")
return segs[len(segs)-1]
}
return ""
}
return u.Host
}
func (self *SLoadbalancerListenerRule) GetRedirectPath() string {
u := self.getRedirectUrl()
if u == nil {
return ""
}
return u.Path
}
+95 -13
View File
@@ -432,40 +432,122 @@ func (region *SRegion) CreateISecurityGroup(conf *cloudprovider.SecurityGroupCre
return region.CreateSecurityGroup(conf.Name)
}
func (region *SRegion) getIAppLBs() ([]cloudprovider.ICloudLoadbalancer, error) {
lbs := []SLoadbalancer{}
params := url.Values{}
params.Set("api-version", "2021-02-01")
err := region.list("Microsoft.Network/applicationGateways", params, &lbs)
if err != nil {
return nil, errors.Wrapf(err, "list")
}
ilbs := make([]cloudprovider.ICloudLoadbalancer, len(lbs))
for i := range lbs {
lbs[i].region = region
ilbs[i] = &lbs[i]
}
return ilbs, nil
}
func (region *SRegion) getINetworkLBs() ([]cloudprovider.ICloudLoadbalancer, error) {
lbs := []SLoadbalancer{}
params := url.Values{}
params.Set("api-version", "2021-02-01")
err := region.list("Microsoft.Network/loadBalancers", params, &lbs)
if err != nil {
return nil, errors.Wrapf(err, "list")
}
ilbs := make([]cloudprovider.ICloudLoadbalancer, len(lbs))
for i := range lbs {
lbs[i].region = region
ilbs[i] = &lbs[i]
}
return ilbs, nil
}
func (region *SRegion) GetILoadBalancers() ([]cloudprovider.ICloudLoadbalancer, error) {
return nil, cloudprovider.ErrNotImplemented
appLbs, err := region.getIAppLBs()
if err != nil {
return nil, errors.Wrap(err, "GetIAppLBs")
}
netLbs, err := region.getINetworkLBs()
if err != nil {
return nil, errors.Wrap(err, "GetINetworkLBs")
}
lbs := []cloudprovider.ICloudLoadbalancer{}
lbs = append(lbs, appLbs...)
lbs = append(lbs, netLbs...)
return lbs, nil
}
func (region *SRegion) GetILoadBalancerById(loadbalancerId string) (cloudprovider.ICloudLoadbalancer, error) {
return nil, cloudprovider.ErrNotImplemented
lb := SLoadbalancer{}
params := url.Values{}
params.Set("api-version", "2021-02-01")
err := region.get(loadbalancerId, params, &lb)
if err != nil {
return nil, errors.Wrapf(err, "get")
}
lb.region = region
return &lb, nil
}
func (region *SRegion) GetILoadBalancerAclById(aclId string) (cloudprovider.ICloudLoadbalancerAcl, error) {
return nil, cloudprovider.ErrNotImplemented
return nil, errors.Wrap(cloudprovider.ErrNotSupported, "GetILoadBalancerAclById")
}
func (region *SRegion) GetILoadBalancerCertificateById(certId string) (cloudprovider.ICloudLoadbalancerCertificate, error) {
return nil, cloudprovider.ErrNotImplemented
}
segs := strings.Split(certId, "/sslCertificates")
if len(segs[0]) > 0 {
lb, err := region.GetILoadBalancerById(segs[0])
if err != nil {
return nil, errors.Wrap(err, "GetILoadBalancerById")
}
func (region *SRegion) CreateILoadBalancerCertificate(cert *cloudprovider.SLoadbalancerCertificate) (cloudprovider.ICloudLoadbalancerCertificate, error) {
return nil, cloudprovider.ErrNotImplemented
}
return lb.(*SLoadbalancer).GetILoadBalancerCertificateById(certId)
}
func (region *SRegion) GetILoadBalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) {
return nil, cloudprovider.ErrNotImplemented
return nil, errors.Wrap(cloudprovider.ErrNotFound, "GetILoadBalancerCertificateById")
}
func (region *SRegion) GetILoadBalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) {
return nil, cloudprovider.ErrNotImplemented
lbs, err := region.GetILoadBalancers()
if err != nil {
return nil, errors.Wrap(err, "GetILoadBalancers")
}
certs := []cloudprovider.ICloudLoadbalancerCertificate{}
for i := range lbs {
_certs, err := lbs[i].(*SLoadbalancer).GetILoadBalancerCertificates()
if err != nil {
return nil, errors.Wrap(err, "GetILoadBalancerCertificates")
}
certs = append(certs, _certs...)
}
return certs, nil
}
func (region *SRegion) CreateILoadBalancerCertificate(cert *cloudprovider.SLoadbalancerCertificate) (cloudprovider.ICloudLoadbalancerCertificate, error) {
return nil, errors.Wrap(cloudprovider.ErrNotImplemented, "CreateILoadBalancerCertificate")
}
func (region *SRegion) GetILoadBalancerAcls() ([]cloudprovider.ICloudLoadbalancerAcl, error) {
return nil, errors.Wrap(cloudprovider.ErrNotSupported, "GetILoadBalancerAcls")
}
func (region *SRegion) CreateILoadBalancer(loadbalancer *cloudprovider.SLoadbalancer) (cloudprovider.ICloudLoadbalancer, error) {
return nil, cloudprovider.ErrNotImplemented
return nil, errors.Wrap(cloudprovider.ErrNotImplemented, "GetILoadBalancerCertificates")
}
func (region *SRegion) CreateILoadBalancerAcl(acl *cloudprovider.SLoadbalancerAccessControlList) (cloudprovider.ICloudLoadbalancerAcl, error) {
return nil, cloudprovider.ErrNotImplemented
return nil, errors.Wrap(cloudprovider.ErrNotImplemented, "CreateILoadBalancerAcl")
}
func (region *SRegion) GetIBuckets() ([]cloudprovider.ICloudBucket, error) {
+125
View File
@@ -0,0 +1,125 @@
package shell
import (
"strings"
"yunion.io/x/onecloud/pkg/multicloud/azure"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type LoadbalancerListOptions struct {
}
shellutils.R(&LoadbalancerListOptions{}, "lb-list", "List loadbalancers", func(cli *azure.SRegion, args *LoadbalancerListOptions) error {
lbs, err := cli.GetILoadBalancers()
if err != nil {
return err
}
printList(lbs, len(lbs), 0, 0, []string{})
return nil
})
type LoadbalancerOptions struct {
ID string `help:"ID of loadbalancer"`
}
shellutils.R(&LoadbalancerOptions{}, "lb-show", "Show loadbalancer", func(cli *azure.SRegion, args *LoadbalancerOptions) error {
lb, err := cli.GetILoadBalancerById(args.ID)
if err != nil {
return err
}
printObject(lb)
return nil
})
shellutils.R(&LoadbalancerListOptions{}, "lbcert-list", "List loadbalancers certs", func(cli *azure.SRegion, args *LoadbalancerListOptions) error {
certs, err := cli.GetILoadBalancerCertificates()
if err != nil {
return err
}
printList(certs, len(certs), 0, 0, []string{})
return nil
})
type LoadbalancerCertOptions struct {
ID string `help:"ID of loadbalancer cert"`
}
shellutils.R(&LoadbalancerCertOptions{}, "lbcert-show", "Show loadbalancer cert", func(cli *azure.SRegion, args *LoadbalancerCertOptions) error {
cert, err := cli.GetILoadBalancerCertificateById(args.ID)
if err != nil {
return err
}
printObject(cert)
return nil
})
shellutils.R(&LoadbalancerOptions{}, "lbl-list", "List loadbalancer listeners", func(cli *azure.SRegion, args *LoadbalancerOptions) error {
lb, err := cli.GetILoadBalancerById(args.ID)
if err != nil {
return err
}
lbl, err := lb.GetILoadBalancerListeners()
if err != nil {
return err
}
printList(lbl, len(lbl), 0, 0, []string{})
return nil
})
shellutils.R(&LoadbalancerOptions{}, "lbbg-list", "List loadbalancer listeners", func(cli *azure.SRegion, args *LoadbalancerOptions) error {
lb, err := cli.GetILoadBalancerById(args.ID)
if err != nil {
return err
}
lbbgs, err := lb.GetILoadBalancerBackendGroups()
if err != nil {
return err
}
printList(lbbgs, len(lbbgs), 0, 0, []string{})
return nil
})
type LoadbalancerBackendOptions struct {
BGID string `help:"ID of loadbalancer backendgroup"`
}
shellutils.R(&LoadbalancerBackendOptions{}, "lbb-list", "List loadbalancer listeners", func(cli *azure.SRegion, args *LoadbalancerBackendOptions) error {
lb, err := cli.GetILoadBalancerById(strings.Split(args.BGID, "/backendAddressPools")[0])
if err != nil {
return err
}
lbbg, err := lb.GetILoadBalancerBackendGroupById(args.BGID)
if err != nil {
return err
}
lbbs, err := lbbg.GetILoadbalancerBackends()
if err != nil {
return err
}
printList(lbbs, len(lbbs), 0, 0, []string{})
return nil
})
type LoadbalancerRuleOptions struct {
LISTENID string `help:"ID of loadbalancer listener"`
}
shellutils.R(&LoadbalancerRuleOptions{}, "lbr-list", "List loadbalancer listener rules", func(cli *azure.SRegion, args *LoadbalancerRuleOptions) error {
lb, err := cli.GetILoadBalancerById(strings.Split(args.LISTENID, "/urlPathMaps")[0])
if err != nil {
return err
}
lbl, err := lb.GetILoadBalancerListenerById(args.LISTENID)
if err != nil {
return err
}
lbrs, err := lbl.GetILoadbalancerListenerRules()
if err != nil {
return err
}
printList(lbrs, len(lbrs), 0, 0, []string{})
return nil
})
}
@@ -36,6 +36,7 @@ type Loadbalancer struct {
type SElbListener struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
multicloud.HuaweiTags
lb *SLoadbalancer
acl *SElbACL
@@ -683,3 +684,11 @@ func (self *SRegion) CreateLoadBalancerPolicy(listenerID string, rule *cloudprov
return l7policy, nil
}
func (self *SElbListener) GetClientIdleTimeout() int {
return 0
}
func (self *SElbListener) GetBackendConnectTimeout() int {
return 0
}
@@ -26,6 +26,7 @@ import (
type SElbListenerPolicy struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
multicloud.HuaweiTags
region *SRegion
lb *SLoadbalancer
+24
View File
@@ -0,0 +1,24 @@
package multicloud
type SLoadbalancerRedirectBase struct {
}
func (self *SLoadbalancerRedirectBase) GetRedirect() string {
return ""
}
func (self *SLoadbalancerRedirectBase) GetRedirectCode() int64 {
return 0
}
func (self *SLoadbalancerRedirectBase) GetRedirectScheme() string {
return ""
}
func (self *SLoadbalancerRedirectBase) GetRedirectHost() string {
return ""
}
func (self *SLoadbalancerRedirectBase) GetRedirectPath() string {
return ""
}
@@ -38,6 +38,7 @@ type SLoadbalancerL7RuleCreateParams struct {
type SLoadbalancerL7Rule struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
multicloud.OpenStackTags
policy *SLoadbalancerL7Policy
CreatedAt string `json:"created_at"`
@@ -85,6 +85,7 @@ type SInsertHeaders struct {
type SLoadbalancerListener struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
multicloud.OpenStackTags
region *SRegion
l7policies []SLoadbalancerL7Policy
@@ -763,3 +764,11 @@ func (listener *SLoadbalancerListener) Sync(ctx context.Context, lblis *cloudpro
func (listener *SLoadbalancerListener) GetProjectId() string {
return listener.ProjectID
}
func (listener *SLoadbalancerListener) GetClientIdleTimeout() int {
return 0
}
func (listener *SLoadbalancerListener) GetBackendConnectTimeout() int {
return 0
}
@@ -70,6 +70,7 @@ type healthCheck struct {
type SLBListener struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
multicloud.QcloudTags
lb *SLoadbalancer
@@ -873,3 +874,11 @@ func certificateParams(t LB_TYPE, params map[string]string, cert *certificate, p
func (self *SLBListener) GetProjectId() string {
return self.lb.GetProjectId()
}
func (self *SLBListener) GetClientIdleTimeout() int {
return 0
}
func (self *SLBListener) GetBackendConnectTimeout() int {
return 0
}
@@ -29,6 +29,7 @@ import (
type SLBListenerRule struct {
multicloud.SResourceBase
multicloud.SLoadbalancerRedirectBase
multicloud.QcloudTags
listener *SLBListener