mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-06-04 08:24:26 +08:00
support gcp regional lb sync
This commit is contained in:
@@ -332,6 +332,7 @@ const (
|
||||
LB_SCHEDULER_SCH = "sch" // source-ip-based consistent hash
|
||||
LB_SCHEDULER_TCH = "tch" // 4-tuple-based consistent hash
|
||||
LB_SCHEDULER_QCH = "qch"
|
||||
LB_SCHEDULER_MH = "mh" // maglev consistent hash
|
||||
)
|
||||
|
||||
var LB_SCHEDULER_TYPES = choices.NewChoices(
|
||||
|
||||
@@ -248,8 +248,12 @@ func (self *SGoogleClient) ecsGet(resource string, retval interface{}) error {
|
||||
}
|
||||
|
||||
func (self *SGoogleClient) ecsList(resource string, params map[string]string) (jsonutils.JSONObject, error) {
|
||||
return self._ecsList("GET", resource, params)
|
||||
}
|
||||
|
||||
func (self *SGoogleClient) _ecsList(method, resource string, params map[string]string) (jsonutils.JSONObject, error) {
|
||||
resource = fmt.Sprintf("projects/%s/%s", self.projectId, resource)
|
||||
return jsonRequest(self.client, "GET", GOOGLE_COMPUTE_DOMAIN, GOOGLE_API_VERSION, resource, params, nil, self.debug)
|
||||
return jsonRequest(self.client, httputils.THttpMethod(method), GOOGLE_COMPUTE_DOMAIN, GOOGLE_API_VERSION, resource, params, nil, self.debug)
|
||||
}
|
||||
|
||||
func (self *SGoogleClient) managerList(resource string, params map[string]string) (jsonutils.JSONObject, error) {
|
||||
@@ -320,6 +324,10 @@ func (self *SGoogleClient) iamListAll(resource string, params map[string]string,
|
||||
}
|
||||
|
||||
func (self *SGoogleClient) ecsListAll(resource string, params map[string]string, retval interface{}) error {
|
||||
return self._ecsListAll("GET", resource, params, retval)
|
||||
}
|
||||
|
||||
func (self *SGoogleClient) _ecsListAll(method string, resource string, params map[string]string, retval interface{}) error {
|
||||
if params == nil {
|
||||
params = map[string]string{}
|
||||
}
|
||||
@@ -328,7 +336,7 @@ func (self *SGoogleClient) ecsListAll(resource string, params map[string]string,
|
||||
params["maxResults"] = "500"
|
||||
for {
|
||||
params["pageToken"] = nextPageToken
|
||||
resp, err := self.ecsList(resource, params)
|
||||
resp, err := self._ecsList(method, resource, params)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "ecsList")
|
||||
}
|
||||
@@ -926,7 +934,7 @@ func (self *SGoogleClient) 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,
|
||||
|
||||
422
pkg/multicloud/google/loadbalancer.go
Normal file
422
pkg/multicloud/google/loadbalancer.go
Normal file
@@ -0,0 +1,422 @@
|
||||
package google
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
// 全球负载均衡 https://cloud.google.com/compute/docs/reference/rest/v1/globalAddresses/list
|
||||
// 区域负载均衡 https://cloud.google.com/compute/docs/reference/rest/v1/addresses
|
||||
// https://cloud.google.com/compute/docs/reference/rest/v1/targetHttpProxies/get
|
||||
// https://cloud.google.com/compute/docs/reference/rest/v1/targetGrpcProxies/get
|
||||
// https://cloud.google.com/compute/docs/reference/rest/v1/targetHttpsProxies/get
|
||||
// https://cloud.google.com/compute/docs/reference/rest/v1/targetSslProxies/get
|
||||
// https://cloud.google.com/compute/docs/reference/rest/v1/targetTcpProxies/get
|
||||
|
||||
type SLoadbalancer struct {
|
||||
SResourceBase
|
||||
region *SRegion
|
||||
urlMap *SUrlMap // http & https LB
|
||||
backendServices []SBackendServices // tcp & udp LB. 或者 http & https 后端
|
||||
instanceGroups []SInstanceGroup
|
||||
healthChecks []HealthChecks
|
||||
|
||||
forwardRules []SForwardingRule // 服务IP地址
|
||||
isHttpLb bool // 标记是否为http/https lb
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetStatus() string {
|
||||
return api.LB_STATUS_ENABLED
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) Refresh() error {
|
||||
lb, err := self.region.GetLoadbalancer(self.GetGlobalId())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetLoadbalancer")
|
||||
}
|
||||
|
||||
err = jsonutils.Update(self, &lb)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Refresh.Update")
|
||||
}
|
||||
|
||||
self.healthChecks = nil
|
||||
self.instanceGroups = nil
|
||||
self.forwardRules = nil
|
||||
if self.isHttpLb {
|
||||
bss, err := self.GetBackendServices()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetForwardingRules")
|
||||
}
|
||||
self.backendServices = bss
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) IsEmulated() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetSysTags() map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetTags() (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) SetTags(tags map[string]string, replace bool) error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetProjectId() string {
|
||||
return self.region.GetProjectId()
|
||||
}
|
||||
|
||||
/*
|
||||
对应forwardingRules地址,存在多个前端IP的情况下,只展示按拉丁字母排序最前的一个地址。其他地址需要到详情中查看
|
||||
*/
|
||||
func (self *SLoadbalancer) GetAddress() string {
|
||||
frs, err := self.GetForwardingRules()
|
||||
if err != nil {
|
||||
log.Errorf("GetAddress.GetForwardingRules %s", err)
|
||||
}
|
||||
|
||||
for i := range frs {
|
||||
if frs[i].LoadBalancingScheme != "EXTERNAL" {
|
||||
return frs[i].IPAddress
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetAddressType() string {
|
||||
eip, err := self.GetIEIP()
|
||||
if err != nil {
|
||||
return api.LB_ADDR_TYPE_INTRANET
|
||||
}
|
||||
if eip == nil {
|
||||
return api.LB_ADDR_TYPE_INTRANET
|
||||
}
|
||||
return api.LB_ADDR_TYPE_INTERNET
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetNetworkType() string {
|
||||
return api.LB_NETWORK_TYPE_VPC
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetNetworkIds() []string {
|
||||
igs, err := self.GetInstanceGroups()
|
||||
if err != nil {
|
||||
log.Errorf("GetInstanceGroups %s", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
selfLinks := make([]string, 0)
|
||||
networkIds := make([]string, 0)
|
||||
for i := range igs {
|
||||
if utils.IsInStringArray(igs[i].Network, selfLinks) {
|
||||
selfLinks = append(selfLinks, igs[i].Network)
|
||||
network := SResourceBase{
|
||||
Name: "",
|
||||
SelfLink: igs[i].Network,
|
||||
}
|
||||
networkIds = append(networkIds, network.GetGlobalId())
|
||||
}
|
||||
}
|
||||
|
||||
return networkIds
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetVpcId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetZoneId() string {
|
||||
igs, err := self.GetInstanceGroups()
|
||||
if err != nil {
|
||||
log.Errorf("GetInstanceGroups %s", err)
|
||||
return ""
|
||||
}
|
||||
|
||||
for i := range igs {
|
||||
if len(igs[i].Zone) > 0 {
|
||||
zone := SResourceBase{
|
||||
Name: "",
|
||||
SelfLink: igs[i].Zone,
|
||||
}
|
||||
|
||||
return zone.GetGlobalId()
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetZone1Id() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetLoadbalancerSpec() string {
|
||||
if self.isHttpLb {
|
||||
return "regional_http_lb"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("regional_%s", strings.ToLower(self.backendServices[0].Protocol))
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetChargeType() string {
|
||||
return api.LB_CHARGE_TYPE_POSTPAID
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetEgressMbps() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetIEIP() (cloudprovider.ICloudEIP, error) {
|
||||
frs, err := self.GetForwardingRules()
|
||||
if err != nil {
|
||||
log.Errorf("GetAddress.GetForwardingRules %s", err)
|
||||
}
|
||||
|
||||
for i := range frs {
|
||||
if frs[i].LoadBalancingScheme == "EXTERNAL" {
|
||||
eips, err := self.region.GetEips(frs[i].IPAddress, 0, "")
|
||||
if err != nil {
|
||||
log.Errorf("GetEips %s", err)
|
||||
}
|
||||
|
||||
if len(eips) > 0 {
|
||||
return &eips[0], nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) Delete(ctx context.Context) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) Start() error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) Stop() error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetILoadBalancerListeners() ([]cloudprovider.ICloudLoadbalancerListener, error) {
|
||||
lbls, err := self.GetLoadbalancerListeners()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetLoadbalancerListeners")
|
||||
}
|
||||
|
||||
ilbls := make([]cloudprovider.ICloudLoadbalancerListener, len(lbls))
|
||||
for i := range lbls {
|
||||
ilbls[i] = &lbls[i]
|
||||
}
|
||||
|
||||
return ilbls, nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetILoadBalancerBackendGroups() ([]cloudprovider.ICloudLoadbalancerBackendGroup, error) {
|
||||
lbbgs, err := self.GetLoadbalancerBackendGroups()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetLoadbalancerBackendGroups")
|
||||
}
|
||||
|
||||
ilbbgs := make([]cloudprovider.ICloudLoadbalancerBackendGroup, len(lbbgs))
|
||||
for i := range lbbgs {
|
||||
ilbbgs[i] = &lbbgs[i]
|
||||
}
|
||||
|
||||
return ilbbgs, nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) CreateILoadBalancerBackendGroup(group *cloudprovider.SLoadbalancerBackendGroup) (cloudprovider.ICloudLoadbalancerBackendGroup, error) {
|
||||
return nil, cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetILoadBalancerBackendGroupById(groupId string) (cloudprovider.ICloudLoadbalancerBackendGroup, error) {
|
||||
lbbgs, err := self.GetLoadbalancerBackendGroups()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetLoadbalancerBackendGroups")
|
||||
}
|
||||
|
||||
for i := range lbbgs {
|
||||
if lbbgs[i].GetGlobalId() == groupId {
|
||||
return &lbbgs[i], nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) CreateILoadBalancerListener(ctx context.Context, listener *cloudprovider.SLoadbalancerListener) (cloudprovider.ICloudLoadbalancerListener, error) {
|
||||
return nil, cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetILoadBalancerListenerById(listenerId string) (cloudprovider.ICloudLoadbalancerListener, error) {
|
||||
lbls, err := self.GetLoadbalancerListeners()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetLoadbalancerBackendGroups")
|
||||
}
|
||||
|
||||
for i := range lbls {
|
||||
if lbls[i].GetGlobalId() == listenerId {
|
||||
return &lbls[i], nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
// GET https://compute.googleapis.com/compute/v1/projects/{project}/aggregated/targetHttpProxies 前端监听
|
||||
// tcp lb backend type: backend service
|
||||
func (self *SRegion) GetRegionalTcpLoadbalancers() ([]SLoadbalancer, error) {
|
||||
bss, err := self.GetRegionalBackendServices("protocol eq TCP")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetRegionalBackendServices")
|
||||
}
|
||||
|
||||
lbs := make([]SLoadbalancer, len(bss))
|
||||
for i := range bss {
|
||||
lbs[i] = SLoadbalancer{
|
||||
region: self,
|
||||
SResourceBase: SResourceBase{
|
||||
Name: bss[i].Name,
|
||||
SelfLink: bss[i].SelfLink,
|
||||
},
|
||||
urlMap: nil,
|
||||
backendServices: []SBackendServices{bss[i]},
|
||||
forwardRules: nil,
|
||||
}
|
||||
}
|
||||
|
||||
return lbs, nil
|
||||
}
|
||||
|
||||
// udp lb backend type: backend service
|
||||
func (self *SRegion) GetRegionalUdpLoadbalancers() ([]SLoadbalancer, error) {
|
||||
bss, err := self.GetRegionalBackendServices("protocol eq UDP")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetRegionalBackendServices")
|
||||
}
|
||||
|
||||
lbs := make([]SLoadbalancer, len(bss))
|
||||
for i := range bss {
|
||||
lbs[i] = SLoadbalancer{
|
||||
region: self,
|
||||
SResourceBase: SResourceBase{
|
||||
Name: bss[i].Name,
|
||||
SelfLink: bss[i].SelfLink,
|
||||
},
|
||||
urlMap: nil,
|
||||
backendServices: []SBackendServices{bss[i]},
|
||||
forwardRules: nil,
|
||||
}
|
||||
}
|
||||
|
||||
return lbs, nil
|
||||
}
|
||||
|
||||
// http&https lb: urlmaps
|
||||
func (self *SRegion) GetRegionalHTTPLoadbalancers() ([]SLoadbalancer, error) {
|
||||
ums, err := self.GetRegionalUrlMaps("")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetRegionalUrlMaps")
|
||||
}
|
||||
|
||||
lbs := make([]SLoadbalancer, len(ums))
|
||||
for i := range ums {
|
||||
lbs[i] = SLoadbalancer{
|
||||
region: self,
|
||||
SResourceBase: SResourceBase{
|
||||
Name: ums[i].Name,
|
||||
SelfLink: ums[i].SelfLink,
|
||||
},
|
||||
urlMap: &ums[i],
|
||||
backendServices: nil,
|
||||
forwardRules: nil,
|
||||
isHttpLb: true,
|
||||
}
|
||||
}
|
||||
|
||||
return lbs, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetRegionalLoadbalancers() ([]SLoadbalancer, error) {
|
||||
lbs := make([]SLoadbalancer, 0)
|
||||
funcs := []func() ([]SLoadbalancer, error){self.GetRegionalHTTPLoadbalancers, self.GetRegionalTcpLoadbalancers, self.GetRegionalUdpLoadbalancers}
|
||||
for i := range funcs {
|
||||
_lbs, err := funcs[i]()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetRegionalLoadbalancers")
|
||||
}
|
||||
lbs = append(lbs, _lbs...)
|
||||
}
|
||||
|
||||
return lbs, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetLoadbalancer(resourceId string) (SLoadbalancer, error) {
|
||||
lb := SLoadbalancer{}
|
||||
var err error
|
||||
if strings.Contains(resourceId, "/urlMaps/") {
|
||||
ret := SUrlMap{}
|
||||
err = self.Get(resourceId, &ret)
|
||||
lb.isHttpLb = true
|
||||
lb.urlMap = &ret
|
||||
lb.SResourceBase = SResourceBase{
|
||||
Name: ret.Name,
|
||||
SelfLink: ret.SelfLink,
|
||||
}
|
||||
} else {
|
||||
ret := SBackendServices{}
|
||||
err = self.Get(resourceId, &ret)
|
||||
lb.backendServices = []SBackendServices{ret}
|
||||
lb.SResourceBase = SResourceBase{
|
||||
Name: ret.Name,
|
||||
SelfLink: ret.SelfLink,
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return lb, errors.Wrapf(err, "get")
|
||||
}
|
||||
|
||||
lb.region = self
|
||||
return lb, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetILoadBalancers() ([]cloudprovider.ICloudLoadbalancer, error) {
|
||||
lbs, err := self.GetRegionalLoadbalancers()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetRegionalLoadbalancers")
|
||||
}
|
||||
ilbs := []cloudprovider.ICloudLoadbalancer{}
|
||||
for i := range lbs {
|
||||
ilbs = append(ilbs, &lbs[i])
|
||||
}
|
||||
return ilbs, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetILoadBalancerById(loadbalancerId string) (cloudprovider.ICloudLoadbalancer, error) {
|
||||
lb, err := self.GetLoadbalancer(loadbalancerId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetLoadbalancer")
|
||||
}
|
||||
return &lb, nil
|
||||
}
|
||||
186
pkg/multicloud/google/loadbalancer_backend.go
Normal file
186
pkg/multicloud/google/loadbalancer_backend.go
Normal file
@@ -0,0 +1,186 @@
|
||||
package google
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SLoadbalancerBackend struct {
|
||||
lbbg *SLoadBalancerBackendGroup
|
||||
|
||||
backendService SBackendServices //
|
||||
instanceGroup SInstanceGroup // 实例组
|
||||
Backend SInstanceGroupInstance // backend
|
||||
|
||||
Port int `json:"port"`
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerBackend) GetId() string {
|
||||
return fmt.Sprintf("%s::%s::%s::%d", self.lbbg.GetGlobalId(), self.instanceGroup.GetGlobalId(), self.GetBackendId(), self.Port)
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerBackend) GetName() string {
|
||||
segs := strings.Split(self.Backend.Instance, "/")
|
||||
name := ""
|
||||
if len(segs) > 0 {
|
||||
name = segs[len(segs)-1]
|
||||
}
|
||||
return fmt.Sprintf("%s::%s::%d", self.instanceGroup.GetName(), name, self.Port)
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerBackend) GetGlobalId() string {
|
||||
return self.GetId()
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerBackend) GetStatus() string {
|
||||
return api.LB_STATUS_ENABLED
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerBackend) Refresh() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerBackend) IsEmulated() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
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 cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerBackend) GetProjectId() string {
|
||||
return self.lbbg.GetProjectId()
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerBackend) GetWeight() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerBackend) GetPort() int {
|
||||
return self.Port
|
||||
}
|
||||
|
||||
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 {
|
||||
r := SResourceBase{
|
||||
Name: "",
|
||||
SelfLink: self.Backend.Instance,
|
||||
}
|
||||
return r.GetGlobalId()
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerBackend) GetIpAddress() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerBackend) SyncConf(ctx context.Context, port, weight int) error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadBalancerBackendGroup) GetLoadbalancerBackends() ([]SLoadbalancerBackend, error) {
|
||||
if self.backends != nil {
|
||||
return self.backends, nil
|
||||
}
|
||||
|
||||
_igs, err := self.lb.GetInstanceGroupsMap()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetInstanceGroupsMap")
|
||||
}
|
||||
|
||||
igs := make([]SInstanceGroup, 0)
|
||||
for i := range self.backendService.Backends {
|
||||
backend := self.backendService.Backends[i]
|
||||
if v, ok := _igs[backend.Group]; ok {
|
||||
igs = append(igs, v)
|
||||
}
|
||||
}
|
||||
|
||||
ret := make([]SLoadbalancerBackend, 0)
|
||||
for i := range igs {
|
||||
ig := igs[i]
|
||||
// http lb
|
||||
if self.lb.isHttpLb {
|
||||
for j := range ig.NamedPorts {
|
||||
np := ig.NamedPorts[j]
|
||||
if np.Name != self.backendService.PortName {
|
||||
continue
|
||||
}
|
||||
|
||||
bs, err := ig.GetInstances()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetInstances")
|
||||
}
|
||||
|
||||
for n := range bs {
|
||||
backend := SLoadbalancerBackend{
|
||||
lbbg: self,
|
||||
backendService: self.backendService,
|
||||
instanceGroup: ig,
|
||||
Backend: bs[n],
|
||||
Port: int(np.Port),
|
||||
}
|
||||
|
||||
ret = append(ret, backend)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// tcp & udp lb
|
||||
bs, err := ig.GetInstances()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetInstances")
|
||||
}
|
||||
|
||||
frs, err := self.lb.GetForwardingRules()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetForwardingRules")
|
||||
}
|
||||
|
||||
for m := range frs {
|
||||
fr := frs[m]
|
||||
for p := range fr.Ports {
|
||||
port, _ := strconv.Atoi(fr.Ports[p])
|
||||
if port <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
for n := range bs {
|
||||
backend := SLoadbalancerBackend{
|
||||
lbbg: self,
|
||||
backendService: self.backendService,
|
||||
instanceGroup: ig,
|
||||
Backend: bs[n],
|
||||
Port: port,
|
||||
}
|
||||
|
||||
ret = append(ret, backend)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.backends = ret
|
||||
return ret, nil
|
||||
}
|
||||
154
pkg/multicloud/google/loadbalancer_backendgroup.go
Normal file
154
pkg/multicloud/google/loadbalancer_backendgroup.go
Normal file
@@ -0,0 +1,154 @@
|
||||
package google
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SLoadBalancerBackendGroup struct {
|
||||
lb *SLoadbalancer
|
||||
backends []SLoadbalancerBackend
|
||||
|
||||
backendService SBackendServices //
|
||||
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func (self *SLoadBalancerBackendGroup) GetId() string {
|
||||
return self.Id
|
||||
}
|
||||
|
||||
func (self *SLoadBalancerBackendGroup) GetName() string {
|
||||
return self.Name
|
||||
}
|
||||
|
||||
func (self *SLoadBalancerBackendGroup) GetGlobalId() string {
|
||||
return self.backendService.GetGlobalId()
|
||||
}
|
||||
|
||||
func (self *SLoadBalancerBackendGroup) GetStatus() string {
|
||||
return api.LB_STATUS_ENABLED
|
||||
}
|
||||
|
||||
func (self *SLoadBalancerBackendGroup) Refresh() error {
|
||||
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 nil, nil
|
||||
}
|
||||
|
||||
func (self *SLoadBalancerBackendGroup) SetTags(tags map[string]string, replace bool) error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadBalancerBackendGroup) GetProjectId() string {
|
||||
return self.lb.GetProjectId()
|
||||
}
|
||||
|
||||
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.GetGlobalId()
|
||||
}
|
||||
|
||||
func (self *SLoadBalancerBackendGroup) GetILoadbalancerBackends() ([]cloudprovider.ICloudLoadbalancerBackend, error) {
|
||||
backends, err := self.GetLoadbalancerBackends()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetLoadbalancerBackends")
|
||||
}
|
||||
|
||||
ibackends := make([]cloudprovider.ICloudLoadbalancerBackend, len(backends))
|
||||
for i := range backends {
|
||||
ibackends[i] = &backends[i]
|
||||
}
|
||||
|
||||
return ibackends, nil
|
||||
}
|
||||
|
||||
func (self *SLoadBalancerBackendGroup) GetILoadbalancerBackendById(backendId string) (cloudprovider.ICloudLoadbalancerBackend, error) {
|
||||
backends, err := self.GetLoadbalancerBackends()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetLoadbalancerBackends")
|
||||
}
|
||||
|
||||
for i := range backends {
|
||||
if backends[i].GetGlobalId() == backendId {
|
||||
return &backends[i], nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
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, cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadBalancerBackendGroup) RemoveBackendServer(serverId string, weight int, port int) error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadBalancerBackendGroup) Delete(ctx context.Context) error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadBalancerBackendGroup) Sync(ctx context.Context, group *cloudprovider.SLoadbalancerBackendGroup) error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetLoadbalancerBackendGroups() ([]SLoadBalancerBackendGroup, error) {
|
||||
bss, err := self.GetBackendServices()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetBackendServices")
|
||||
}
|
||||
|
||||
ret := make([]SLoadBalancerBackendGroup, 0)
|
||||
for i := range bss {
|
||||
group := SLoadBalancerBackendGroup{
|
||||
lb: self,
|
||||
backendService: bss[i],
|
||||
Id: bss[i].GetId(),
|
||||
Name: bss[i].GetName(),
|
||||
}
|
||||
|
||||
ret = append(ret, group)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
154
pkg/multicloud/google/loadbalancer_cert.go
Normal file
154
pkg/multicloud/google/loadbalancer_cert.go
Normal file
@@ -0,0 +1,154 @@
|
||||
package google
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SLoadbalancerCertificate struct {
|
||||
region *SRegion
|
||||
SResourceBase
|
||||
cert *x509.Certificate
|
||||
|
||||
ID string `json:"id"`
|
||||
CreationTimestamp string `json:"creationTimestamp"`
|
||||
Certificate string `json:"certificate"`
|
||||
SelfManaged SelfManaged `json:"selfManaged"`
|
||||
Type string `json:"type"`
|
||||
ExpireTime time.Time `json:"expireTime"`
|
||||
Region string `json:"region"`
|
||||
Kind string `json:"kind"`
|
||||
}
|
||||
|
||||
type SelfManaged struct {
|
||||
Certificate string `json:"certificate"`
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerCertificate) GetStatus() string {
|
||||
return api.LB_STATUS_ENABLED
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerCertificate) Refresh() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerCertificate) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerCertificate) GetSysTags() map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerCertificate) GetTags() (map[string]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerCertificate) SetTags(tags map[string]string, replace bool) error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerCertificate) GetProjectId() string {
|
||||
return self.region.GetProjectId()
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerCertificate) Sync(name, privateKey, publickKey string) error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerCertificate) Delete() error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerCertificate) GetCommonName() string {
|
||||
c := self.getCert()
|
||||
if c == nil {
|
||||
return ""
|
||||
}
|
||||
return c.Subject.CommonName
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerCertificate) GetSubjectAlternativeNames() string {
|
||||
c := self.getCert()
|
||||
if c == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
names := []string{}
|
||||
for i := range c.Extensions {
|
||||
names = append(names, string(c.Extensions[i].Value))
|
||||
}
|
||||
|
||||
return strings.Join(names, ",")
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerCertificate) getCert() *x509.Certificate {
|
||||
if self.cert != nil {
|
||||
return self.cert
|
||||
}
|
||||
|
||||
p, _ := pem.Decode([]byte(self.Certificate))
|
||||
c, err := x509.ParseCertificate(p.Bytes)
|
||||
if err != nil {
|
||||
log.Errorf("get certificate %s(%s): %s", self.Name, self.GetId(), err)
|
||||
return nil
|
||||
}
|
||||
|
||||
self.cert = c
|
||||
return c
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerCertificate) GetFingerprint() string {
|
||||
c := self.getCert()
|
||||
if c == nil {
|
||||
return ""
|
||||
}
|
||||
d := sha256.Sum256(c.Raw)
|
||||
return api.LB_TLS_CERT_FINGERPRINT_ALGO_SHA256 + ":" + hex.EncodeToString(d[:])
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerCertificate) GetExpireTime() time.Time {
|
||||
return self.ExpireTime
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerCertificate) GetPublickKey() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerCertificate) GetPrivateKey() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SRegion) GetILoadBalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) {
|
||||
certs, err := self.GetRegionalSslCertificates("")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetRegionalSslCertificates")
|
||||
}
|
||||
|
||||
icerts := make([]cloudprovider.ICloudLoadbalancerCertificate, len(certs))
|
||||
for i := range certs {
|
||||
icerts[i] = &certs[i]
|
||||
}
|
||||
|
||||
return icerts, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetILoadBalancerCertificateById(certId string) (cloudprovider.ICloudLoadbalancerCertificate, error) {
|
||||
ret := SLoadbalancerCertificate{}
|
||||
err := self.Get(certId, &ret)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Get")
|
||||
}
|
||||
ret.region = self
|
||||
return &ret, nil
|
||||
}
|
||||
727
pkg/multicloud/google/loadbalancer_components.go
Normal file
727
pkg/multicloud/google/loadbalancer_components.go
Normal file
@@ -0,0 +1,727 @@
|
||||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SUrlMap struct {
|
||||
SResourceBase
|
||||
|
||||
ID string `json:"id"`
|
||||
CreationTimestamp string `json:"creationTimestamp"`
|
||||
HostRules []HostRule `json:"hostRules"`
|
||||
PathMatchers []PathMatcher `json:"pathMatchers"`
|
||||
DefaultService string `json:"defaultService"`
|
||||
Fingerprint string `json:"fingerprint"`
|
||||
Region string `json:"region"`
|
||||
Kind string `json:"kind"`
|
||||
}
|
||||
|
||||
type SForwardingRule struct {
|
||||
SResourceBase
|
||||
|
||||
ID string `json:"id"`
|
||||
CreationTimestamp string `json:"creationTimestamp"`
|
||||
Description string `json:"description"`
|
||||
Region string `json:"region"`
|
||||
IPAddress string `json:"IPAddress"`
|
||||
IPProtocol string `json:"IPProtocol"`
|
||||
PortRange string `json:"portRange"`
|
||||
Target string `json:"target"`
|
||||
LoadBalancingScheme string `json:"loadBalancingScheme"`
|
||||
Subnetwork string `json:"subnetwork"`
|
||||
Network string `json:"network"`
|
||||
NetworkTier string `json:"networkTier"`
|
||||
LabelFingerprint string `json:"labelFingerprint"`
|
||||
Fingerprint string `json:"fingerprint"`
|
||||
Kind string `json:"kind"`
|
||||
Ports []string `json:"ports"`
|
||||
BackendService string `json:"backendService"`
|
||||
}
|
||||
|
||||
//
|
||||
//type STargetProxy struct {
|
||||
//}
|
||||
//
|
||||
type SBackendServices struct {
|
||||
SResourceBase
|
||||
|
||||
ID string `json:"id"`
|
||||
CreationTimestamp string `json:"creationTimestamp"`
|
||||
Description string `json:"description"`
|
||||
Backends []Backend `json:"backends"`
|
||||
HealthChecks []string `json:"healthChecks"`
|
||||
TimeoutSEC int64 `json:"timeoutSec"`
|
||||
Port int64 `json:"port"`
|
||||
Protocol string `json:"protocol"`
|
||||
Fingerprint string `json:"fingerprint"`
|
||||
PortName string `json:"portName"`
|
||||
SessionAffinity string `json:"sessionAffinity"`
|
||||
AffinityCookieTTLSEC int64 `json:"affinityCookieTtlSec"`
|
||||
Region string `json:"region"`
|
||||
LoadBalancingScheme string `json:"loadBalancingScheme"`
|
||||
ConnectionDraining ConnectionDraining `json:"connectionDraining"`
|
||||
LocalityLBPolicy string `json:"localityLbPolicy"`
|
||||
ConsistentHash ConsistentHash `json:"consistentHash"`
|
||||
Kind string `json:"kind"`
|
||||
EnableCDN bool `json:"enableCDN"`
|
||||
Network string `json:"network"`
|
||||
}
|
||||
|
||||
//
|
||||
//type STargetPool struct {
|
||||
//}
|
||||
|
||||
type STargetHttpProxy struct {
|
||||
SResourceBase
|
||||
|
||||
ID string `json:"id"`
|
||||
CreationTimestamp string `json:"creationTimestamp"`
|
||||
Description string `json:"description"`
|
||||
URLMap string `json:"urlMap"`
|
||||
Region string `json:"region"`
|
||||
ProxyBind bool `json:"proxyBind"`
|
||||
Fingerprint string `json:"fingerprint"`
|
||||
Kind string `json:"kind"`
|
||||
}
|
||||
|
||||
type STargetHttpsProxy struct {
|
||||
SResourceBase
|
||||
|
||||
ID string `json:"id"`
|
||||
CreationTimestamp string `json:"creationTimestamp"`
|
||||
Description string `json:"description"`
|
||||
URLMap string `json:"urlMap"`
|
||||
SSLCertificates []string `json:"sslCertificates"`
|
||||
QuicOverride string `json:"quicOverride"`
|
||||
SSLPolicy string `json:"sslPolicy"`
|
||||
Region string `json:"region"`
|
||||
ProxyBind bool `json:"proxyBind"`
|
||||
ServerTLSPolicy string `json:"serverTlsPolicy"`
|
||||
AuthorizationPolicy string `json:"authorizationPolicy"`
|
||||
Fingerprint string `json:"fingerprint"`
|
||||
Kind string `json:"kind"`
|
||||
}
|
||||
|
||||
type SInstanceGroup struct {
|
||||
SResourceBase
|
||||
region *SRegion
|
||||
instances []SInstanceGroupInstance
|
||||
|
||||
ID string `json:"id"`
|
||||
CreationTimestamp string `json:"creationTimestamp"`
|
||||
Description string `json:"description"`
|
||||
NamedPorts []NamedPort `json:"namedPorts"`
|
||||
Network string `json:"network"`
|
||||
Fingerprint string `json:"fingerprint"`
|
||||
Zone string `json:"zone"`
|
||||
Size int64 `json:"size"`
|
||||
Region string `json:"region"`
|
||||
Subnetwork string `json:"subnetwork"`
|
||||
Kind string `json:"kind"`
|
||||
}
|
||||
|
||||
type SInstanceGroupInstance struct {
|
||||
instanceGroup *SInstanceGroup
|
||||
Instance string `json:"instance"`
|
||||
Status string `json:"status"`
|
||||
NamedPorts []NamedPort `json:"namedPorts"`
|
||||
}
|
||||
|
||||
type NamedPort struct {
|
||||
Name string `json:"name"`
|
||||
Port int64 `json:"port"`
|
||||
}
|
||||
|
||||
type ConsistentHash struct {
|
||||
HTTPCookie HTTPCookie `json:"httpCookie"`
|
||||
MinimumRingSize string `json:"minimumRingSize"`
|
||||
}
|
||||
|
||||
type HTTPCookie struct {
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
TTL TTL `json:"ttl"`
|
||||
}
|
||||
|
||||
type TTL struct {
|
||||
Seconds string `json:"seconds"`
|
||||
Nanos int64 `json:"nanos"`
|
||||
}
|
||||
|
||||
type RouteAction struct {
|
||||
WeightedBackendServices []WeightedBackendService `json:"weightedBackendServices"`
|
||||
URLRewrite URLRewrite `json:"urlRewrite"`
|
||||
Timeout MaxStreamDuration `json:"timeout"`
|
||||
RetryPolicy RetryPolicy `json:"retryPolicy"`
|
||||
RequestMirrorPolicy RequestMirrorPolicy `json:"requestMirrorPolicy"`
|
||||
CorsPolicy CorsPolicy `json:"corsPolicy"`
|
||||
FaultInjectionPolicy FaultInjectionPolicy `json:"faultInjectionPolicy"`
|
||||
MaxStreamDuration MaxStreamDuration `json:"maxStreamDuration"`
|
||||
}
|
||||
|
||||
type CorsPolicy struct {
|
||||
AllowOrigins []string `json:"allowOrigins"`
|
||||
AllowOriginRegexes []string `json:"allowOriginRegexes"`
|
||||
AllowMethods []string `json:"allowMethods"`
|
||||
AllowHeaders []string `json:"allowHeaders"`
|
||||
ExposeHeaders []string `json:"exposeHeaders"`
|
||||
MaxAge int64 `json:"maxAge"`
|
||||
AllowCredentials bool `json:"allowCredentials"`
|
||||
Disabled bool `json:"disabled"`
|
||||
}
|
||||
|
||||
type FaultInjectionPolicy struct {
|
||||
Delay Delay `json:"delay"`
|
||||
Abort Abort `json:"abort"`
|
||||
}
|
||||
|
||||
type Abort struct {
|
||||
HTTPStatus int64 `json:"httpStatus"`
|
||||
Percentage float64 `json:"percentage"`
|
||||
}
|
||||
|
||||
type Delay struct {
|
||||
FixedDelay MaxStreamDuration `json:"fixedDelay"`
|
||||
Percentage float64 `json:"percentage"`
|
||||
}
|
||||
|
||||
type MaxStreamDuration struct {
|
||||
Seconds string `json:"seconds"`
|
||||
Nanos int64 `json:"nanos"`
|
||||
}
|
||||
|
||||
type RequestMirrorPolicy struct {
|
||||
BackendService string `json:"backendService"`
|
||||
}
|
||||
|
||||
type RetryPolicy struct {
|
||||
RetryConditions []string `json:"retryConditions"`
|
||||
NumRetries int64 `json:"numRetries"`
|
||||
PerTryTimeout MaxStreamDuration `json:"perTryTimeout"`
|
||||
}
|
||||
|
||||
type URLRewrite struct {
|
||||
PathPrefixRewrite string `json:"pathPrefixRewrite"`
|
||||
HostRewrite string `json:"hostRewrite"`
|
||||
}
|
||||
|
||||
type WeightedBackendService struct {
|
||||
BackendService string `json:"backendService"`
|
||||
Weight int64 `json:"weight"`
|
||||
HeaderAction HeaderAction `json:"headerAction"`
|
||||
}
|
||||
|
||||
type HeaderAction struct {
|
||||
RequestHeadersToRemove []string `json:"requestHeadersToRemove"`
|
||||
RequestHeadersToAdd []HeadersToAdd `json:"requestHeadersToAdd"`
|
||||
ResponseHeadersToRemove []string `json:"responseHeadersToRemove"`
|
||||
ResponseHeadersToAdd []HeadersToAdd `json:"responseHeadersToAdd"`
|
||||
}
|
||||
|
||||
type HeadersToAdd struct {
|
||||
HeaderName string `json:"headerName"`
|
||||
HeaderValue string `json:"headerValue"`
|
||||
Replace bool `json:"replace"`
|
||||
}
|
||||
|
||||
type URLRedirect struct {
|
||||
HostRedirect string `json:"hostRedirect"`
|
||||
PathRedirect string `json:"pathRedirect"`
|
||||
PrefixRedirect string `json:"prefixRedirect"`
|
||||
RedirectResponseCode string `json:"redirectResponseCode"`
|
||||
HTTPSRedirect bool `json:"httpsRedirect"`
|
||||
StripQuery bool `json:"stripQuery"`
|
||||
}
|
||||
|
||||
type HostRule struct {
|
||||
Description string `json:"description"`
|
||||
Hosts []string `json:"hosts"`
|
||||
PathMatcher string `json:"pathMatcher"`
|
||||
}
|
||||
|
||||
type PathMatcher struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
DefaultService string `json:"defaultService"`
|
||||
DefaultRouteAction RouteAction `json:"defaultRouteAction"`
|
||||
DefaultURLRedirect URLRedirect `json:"defaultUrlRedirect"`
|
||||
PathRules []PathRule `json:"pathRules"`
|
||||
RouteRules []RouteRule `json:"routeRules"`
|
||||
HeaderAction HeaderAction `json:"headerAction"`
|
||||
}
|
||||
|
||||
type PathRule struct {
|
||||
Service string `json:"service"`
|
||||
RouteAction RouteAction `json:"routeAction"`
|
||||
URLRedirect URLRedirect `json:"urlRedirect"`
|
||||
Paths []string `json:"paths"`
|
||||
}
|
||||
|
||||
type RouteRule struct {
|
||||
Priority int64 `json:"priority"`
|
||||
Description string `json:"description"`
|
||||
MatchRules []MatchRule `json:"matchRules"`
|
||||
Service string `json:"service"`
|
||||
RouteAction RouteAction `json:"routeAction"`
|
||||
URLRedirect URLRedirect `json:"urlRedirect"`
|
||||
HeaderAction HeaderAction `json:"headerAction"`
|
||||
}
|
||||
|
||||
type MatchRule struct {
|
||||
PrefixMatch string `json:"prefixMatch"`
|
||||
FullPathMatch string `json:"fullPathMatch"`
|
||||
RegexMatch string `json:"regexMatch"`
|
||||
IgnoreCase bool `json:"ignoreCase"`
|
||||
HeaderMatches []HeaderMatch `json:"headerMatches"`
|
||||
QueryParameterMatches []QueryParameterMatch `json:"queryParameterMatches"`
|
||||
MetadataFilters []MetadataFilter `json:"metadataFilters"`
|
||||
}
|
||||
|
||||
type HeaderMatch struct {
|
||||
HeaderName string `json:"headerName"`
|
||||
ExactMatch string `json:"exactMatch"`
|
||||
RegexMatch string `json:"regexMatch"`
|
||||
RangeMatch RangeMatch `json:"rangeMatch"`
|
||||
PresentMatch bool `json:"presentMatch"`
|
||||
PrefixMatch string `json:"prefixMatch"`
|
||||
SuffixMatch string `json:"suffixMatch"`
|
||||
InvertMatch bool `json:"invertMatch"`
|
||||
}
|
||||
|
||||
type RangeMatch struct {
|
||||
RangeStart string `json:"rangeStart"`
|
||||
RangeEnd string `json:"rangeEnd"`
|
||||
}
|
||||
|
||||
type MetadataFilter struct {
|
||||
FilterMatchCriteria string `json:"filterMatchCriteria"`
|
||||
FilterLabels []Header `json:"filterLabels"`
|
||||
}
|
||||
|
||||
type Header struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type QueryParameterMatch struct {
|
||||
Name string `json:"name"`
|
||||
PresentMatch bool `json:"presentMatch"`
|
||||
ExactMatch string `json:"exactMatch"`
|
||||
RegexMatch string `json:"regexMatch"`
|
||||
}
|
||||
|
||||
type Test struct {
|
||||
Description string `json:"description"`
|
||||
Host string `json:"host"`
|
||||
Path string `json:"path"`
|
||||
Headers []Header `json:"headers"`
|
||||
Service string `json:"service"`
|
||||
ExpectedOutputURL string `json:"expectedOutputUrl"`
|
||||
ExpectedRedirectResponseCode int64 `json:"expectedRedirectResponseCode"`
|
||||
}
|
||||
|
||||
type Backend struct {
|
||||
Group string `json:"group"`
|
||||
BalancingMode string `json:"balancingMode"`
|
||||
Failover bool `json:"failover"`
|
||||
}
|
||||
|
||||
type ConnectionDraining struct {
|
||||
DrainingTimeoutSEC int64 `json:"drainingTimeoutSec"`
|
||||
}
|
||||
|
||||
type HealthChecks struct {
|
||||
SResourceBase
|
||||
|
||||
ID string `json:"id"`
|
||||
CreationTimestamp string `json:"creationTimestamp"`
|
||||
Description string `json:"description"`
|
||||
CheckIntervalSEC int64 `json:"checkIntervalSec"`
|
||||
TimeoutSEC int64 `json:"timeoutSec"`
|
||||
UnhealthyThreshold int64 `json:"unhealthyThreshold"`
|
||||
HealthyThreshold int64 `json:"healthyThreshold"`
|
||||
Type string `json:"type"`
|
||||
HTTPSHealthCheck HTTPHealthCheck `json:"httpsHealthCheck"`
|
||||
Region string `json:"region"`
|
||||
Kind string `json:"kind"`
|
||||
Http2HealthCheck HTTPHealthCheck `json:"http2HealthCheck"`
|
||||
TCPHealthCheck TCPHealthCheck `json:"tcpHealthCheck"`
|
||||
SSLHealthCheck SSLHealthCheck `json:"sslHealthCheck"`
|
||||
HTTPHealthCheck HTTPHealthCheck `json:"httpHealthCheck"`
|
||||
}
|
||||
|
||||
type HTTPHealthCheck struct {
|
||||
Port int64 `json:"port"`
|
||||
Host string `json:"host"`
|
||||
RequestPath string `json:"requestPath"`
|
||||
ProxyHeader string `json:"proxyHeader"`
|
||||
Response string `json:"response"`
|
||||
}
|
||||
|
||||
type SSLHealthCheck struct {
|
||||
Port int64 `json:"port"`
|
||||
Request string `json:"request"`
|
||||
Response string `json:"response"`
|
||||
ProxyHeader string `json:"proxyHeader"`
|
||||
}
|
||||
|
||||
type TCPHealthCheck struct {
|
||||
Port int64 `json:"port"`
|
||||
ProxyHeader string `json:"proxyHeader"`
|
||||
}
|
||||
|
||||
type LogConfig struct {
|
||||
Enable bool `json:"enable"`
|
||||
}
|
||||
|
||||
func (self *SInstanceGroup) GetInstances() ([]SInstanceGroupInstance, error) {
|
||||
if self.instances != nil {
|
||||
return self.instances, nil
|
||||
}
|
||||
|
||||
ret := make([]SInstanceGroupInstance, 0)
|
||||
resourceId := strings.Replace(self.GetGlobalId(), fmt.Sprintf("projects/%s/", self.region.GetProjectId()), "", -1)
|
||||
err := self.region.listAll("POST", resourceId+"/listInstances", nil, &ret)
|
||||
if err != nil {
|
||||
if errors.Cause(err) == cloudprovider.ErrNotFound {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return nil, errors.Wrap(err, "ListAll")
|
||||
}
|
||||
|
||||
for i := range ret {
|
||||
ret[i].instanceGroup = self
|
||||
}
|
||||
|
||||
self.instances = ret
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) getLoadbalancerComponents(resource string, filter string, result interface{}) error {
|
||||
url := fmt.Sprintf("regions/%s/%s", self.Name, resource)
|
||||
params := map[string]string{}
|
||||
if len(filter) > 0 {
|
||||
params["filter"] = filter
|
||||
}
|
||||
|
||||
err := self.ListAll(url, params, result)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "ListAll")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SRegion) getInstanceGroups(zoneId, resource string, filter string, result interface{}) error {
|
||||
url := fmt.Sprintf("zones/%s/%s", zoneId, resource)
|
||||
params := map[string]string{}
|
||||
if len(filter) > 0 {
|
||||
params["filter"] = filter
|
||||
}
|
||||
|
||||
err := self.ListAll(url, params, result)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "ListAll")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
As mentioned by Patrick W, there is no direct entity 'load balancer', its just a collection of components.
|
||||
The list seen in the UI that appears to be the load balancer is actually the url-map component,
|
||||
which can be seen via the API with:
|
||||
gcloud compute url-maps list
|
||||
*/
|
||||
func (self *SRegion) GetRegionalUrlMaps(filter string) ([]SUrlMap, error) {
|
||||
ret := make([]SUrlMap, 0)
|
||||
err := self.getLoadbalancerComponents("urlMaps", filter, &ret)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (self *SRegion) GetRegionalBackendServices(filter string) ([]SBackendServices, error) {
|
||||
ret := make([]SBackendServices, 0)
|
||||
err := self.getLoadbalancerComponents("backendServices", filter, &ret)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (self *SRegion) GetRegionalForwardingRule(filter string) ([]SForwardingRule, error) {
|
||||
ret := make([]SForwardingRule, 0)
|
||||
err := self.getLoadbalancerComponents("forwardingRules", filter, &ret)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (self *SRegion) GetRegionalTargetHttpProxies(filter string) ([]STargetHttpProxy, error) {
|
||||
ret := make([]STargetHttpProxy, 0)
|
||||
err := self.getLoadbalancerComponents("targetHttpProxies", filter, &ret)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (self *SRegion) GetRegionalTargetHttpsProxies(filter string) ([]STargetHttpsProxy, error) {
|
||||
ret := make([]STargetHttpsProxy, 0)
|
||||
err := self.getLoadbalancerComponents("targetHttpsProxies", filter, &ret)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (self *SRegion) GetRegionalInstanceGroups(filter string) ([]SInstanceGroup, error) {
|
||||
ret := make([]SInstanceGroup, 0)
|
||||
err := self.getLoadbalancerComponents("instanceGroups", filter, &ret)
|
||||
for i := range ret {
|
||||
ret[i].region = self
|
||||
}
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (self *SRegion) GetRegionalHealthChecks(filter string) ([]HealthChecks, error) {
|
||||
ret := make([]HealthChecks, 0)
|
||||
err := self.getLoadbalancerComponents("healthChecks", filter, &ret)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (self *SRegion) GetGlobalHealthChecks(filter string) ([]HealthChecks, error) {
|
||||
ret := make([]HealthChecks, 0)
|
||||
params := map[string]string{}
|
||||
if len(filter) > 0 {
|
||||
params["filter"] = filter
|
||||
}
|
||||
|
||||
err := self.ListAll("global/healthChecks", params, &ret)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "ListAll")
|
||||
}
|
||||
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (self *SRegion) GetRegionalSslCertificates(filter string) ([]SLoadbalancerCertificate, error) {
|
||||
ret := make([]SLoadbalancerCertificate, 0)
|
||||
err := self.getLoadbalancerComponents("sslCertificates", filter, &ret)
|
||||
for i := range ret {
|
||||
ret[i].region = self
|
||||
}
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetTargetHttpsProxies() ([]STargetHttpsProxy, error) {
|
||||
ret := make([]STargetHttpsProxy, 0)
|
||||
filter := fmt.Sprintf("urlMap eq %s", self.GetId())
|
||||
err := self.region.getLoadbalancerComponents("targetHttpsProxies", filter, &ret)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetTargetHttpProxies() ([]STargetHttpProxy, error) {
|
||||
ret := make([]STargetHttpProxy, 0)
|
||||
filter := fmt.Sprintf("urlMap eq %s", self.GetId())
|
||||
err := self.region.getLoadbalancerComponents("targetHttpProxies", filter, &ret)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// ForwardingRule 目标是: target proxy or backend service
|
||||
// http&https 是由target proxy 转发到后端服务
|
||||
func (self *SLoadbalancer) GetForwardingRules() ([]SForwardingRule, error) {
|
||||
if self.forwardRules != nil {
|
||||
return self.forwardRules, nil
|
||||
}
|
||||
|
||||
hps, err := self.GetTargetHttpProxies()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetTargetHttpProxies")
|
||||
}
|
||||
|
||||
hsps, err := self.GetTargetHttpsProxies()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetTargetHttpsProxies")
|
||||
}
|
||||
|
||||
targets := make([]string, 0)
|
||||
for i := range hps {
|
||||
targets = append(targets, fmt.Sprintf(`(target="%s")`, hps[i].GetId()))
|
||||
}
|
||||
|
||||
for i := range hsps {
|
||||
targets = append(targets, fmt.Sprintf(`(target="%s")`, hsps[i].GetId()))
|
||||
}
|
||||
|
||||
if strings.Contains(self.GetId(), "/backendServices/") {
|
||||
targets = append(targets, fmt.Sprintf(`(backendService="%s")`, self.GetId()))
|
||||
}
|
||||
|
||||
if len(targets) == 0 {
|
||||
return []SForwardingRule{}, nil
|
||||
}
|
||||
|
||||
filter := strings.Join(targets, " OR ")
|
||||
ret := make([]SForwardingRule, 0)
|
||||
err = self.region.getLoadbalancerComponents("forwardingRules", filter, &ret)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetForwardingRules")
|
||||
}
|
||||
|
||||
if len(ret) > 0 {
|
||||
self.forwardRules = ret
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetBackendServices() ([]SBackendServices, error) {
|
||||
if self.isHttpLb && self.urlMap != nil {
|
||||
ret := make([]SBackendServices, 0)
|
||||
ids := []string{self.urlMap.DefaultService}
|
||||
for i := range self.urlMap.PathMatchers {
|
||||
ps := self.urlMap.PathMatchers[i]
|
||||
if len(ps.DefaultService) > 0 && !utils.IsInStringArray(ps.DefaultService, ids) {
|
||||
ids = append(ids, ps.DefaultService)
|
||||
}
|
||||
|
||||
for j := range ps.PathRules {
|
||||
if len(ps.PathRules[j].Service) > 0 && !utils.IsInStringArray(ps.PathRules[j].Service, ids) {
|
||||
ids = append(ids, ps.PathRules[j].Service)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
filters := []string{}
|
||||
for i := range ids {
|
||||
filters = append(filters, fmt.Sprintf(`(selfLink="%s")`, ids[i]))
|
||||
}
|
||||
|
||||
if len(filters) == 0 {
|
||||
return []SBackendServices{}, nil
|
||||
}
|
||||
err := self.region.getLoadbalancerComponents("backendServices", strings.Join(filters, " OR "), &ret)
|
||||
self.backendServices = ret
|
||||
return ret, err
|
||||
}
|
||||
|
||||
return self.backendServices, nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetInstanceGroupsMap() (map[string]SInstanceGroup, error) {
|
||||
igs, err := self.GetInstanceGroups()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetInstanceGroups")
|
||||
}
|
||||
|
||||
ret := make(map[string]SInstanceGroup, 0)
|
||||
for i := range igs {
|
||||
ig := igs[i]
|
||||
ig.region = self.region
|
||||
ret[ig.SelfLink] = ig
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetInstanceGroups() ([]SInstanceGroup, error) {
|
||||
if self.instanceGroups != nil {
|
||||
return self.instanceGroups, nil
|
||||
}
|
||||
|
||||
if self.backendServices == nil {
|
||||
bss, err := self.GetBackendServices()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetBackendServices")
|
||||
}
|
||||
self.backendServices = bss
|
||||
}
|
||||
|
||||
bgs := []string{}
|
||||
for i := range self.backendServices {
|
||||
_bgs := self.backendServices[i].Backends
|
||||
for j := range _bgs {
|
||||
if !utils.IsInStringArray(_bgs[j].Group, bgs) {
|
||||
bgs = append(bgs, _bgs[j].Group)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(bgs) == 0 {
|
||||
return []SInstanceGroup{}, nil
|
||||
}
|
||||
|
||||
regionFilters := []string{}
|
||||
zonesFilter := map[string][]string{}
|
||||
for i := range bgs {
|
||||
if !strings.Contains(bgs[i], "/zones/") {
|
||||
regionFilters = append(regionFilters, fmt.Sprintf(`(selfLink="%s")`, bgs[i]))
|
||||
} else {
|
||||
ig := bgs[i]
|
||||
index := strings.Index(ig, "/zones/")
|
||||
zoneId := strings.Split(ig[index:], "/")[2]
|
||||
if fs, ok := zonesFilter[zoneId]; ok {
|
||||
f := fmt.Sprintf(`(selfLink="%s")`, ig)
|
||||
if !utils.IsInStringArray(f, fs) {
|
||||
fs = append(fs, f)
|
||||
}
|
||||
} else {
|
||||
fs = []string{fmt.Sprintf(`(selfLink="%s")`, ig)}
|
||||
zonesFilter[zoneId] = fs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
igs := make([]SInstanceGroup, 0)
|
||||
// regional instance groups
|
||||
if len(regionFilters) > 0 {
|
||||
_igs, err := self.region.GetRegionalInstanceGroups(strings.Join(regionFilters, " OR "))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetRegionalInstanceGroups")
|
||||
}
|
||||
|
||||
igs = append(igs, _igs...)
|
||||
}
|
||||
|
||||
for z, fs := range zonesFilter {
|
||||
_igs := make([]SInstanceGroup, 0)
|
||||
err := self.region.getInstanceGroups(z, "instanceGroups", strings.Join(fs, " OR "), &_igs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getInstanceGroups")
|
||||
}
|
||||
|
||||
igs = append(igs, _igs...)
|
||||
}
|
||||
|
||||
self.instanceGroups = igs
|
||||
return igs, nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetHealthChecks() ([]HealthChecks, error) {
|
||||
if self.healthChecks != nil {
|
||||
return self.healthChecks, nil
|
||||
}
|
||||
|
||||
hcs, err := self.region.GetRegionalHealthChecks("")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetRegionalHealthChecks")
|
||||
}
|
||||
|
||||
ghcs, err := self.region.GetGlobalHealthChecks("")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetGlobalHealthChecks")
|
||||
}
|
||||
|
||||
self.healthChecks = append(self.healthChecks, ghcs...)
|
||||
self.healthChecks = append(self.healthChecks, hcs...)
|
||||
return self.healthChecks, err
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetHealthCheckMaps() (map[string]HealthChecks, error) {
|
||||
hcs, err := self.GetHealthChecks()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetHealthChecks")
|
||||
}
|
||||
|
||||
ret := map[string]HealthChecks{}
|
||||
for i := range hcs {
|
||||
ret[hcs[i].SelfLink] = hcs[i]
|
||||
}
|
||||
return ret, err
|
||||
}
|
||||
573
pkg/multicloud/google/loadbalancer_listener.go
Normal file
573
pkg/multicloud/google/loadbalancer_listener.go
Normal file
@@ -0,0 +1,573 @@
|
||||
package google
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SLoadbalancerListener struct {
|
||||
lb *SLoadbalancer
|
||||
rules []SLoadbalancerListenerRule
|
||||
forwardRule SForwardingRule // 服务IP地址
|
||||
backendService SBackendServices //
|
||||
httpProxy *STargetHttpProxy // http
|
||||
httpsProxy *STargetHttpsProxy // https
|
||||
healthChecks []HealthChecks
|
||||
|
||||
ForwardRuleName string `json:"forward_rule_name"`
|
||||
BackendServiceName string `json:"backend_service_name"`
|
||||
Protocol string `json:"protocol"`
|
||||
Port string `json:"port"` // 监听端口
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetId() string {
|
||||
return fmt.Sprintf("%s::%s::%s", self.forwardRule.GetGlobalId(), self.backendService.GetGlobalId(), self.Port)
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetName() string {
|
||||
return fmt.Sprintf("%s::%s::%s", self.forwardRule.GetName(), self.backendService.GetName(), self.Port)
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetGlobalId() string {
|
||||
return self.GetId()
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetStatus() string {
|
||||
return api.LB_STATUS_ENABLED
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) Refresh() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) IsEmulated() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetSysTags() map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetTags() (map[string]string, error) {
|
||||
if len(self.forwardRule.IPAddress) > 0 {
|
||||
return map[string]string{"FrontendIP": self.forwardRule.IPAddress}, nil
|
||||
}
|
||||
|
||||
return map[string]string{}, nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) SetTags(tags map[string]string, replace bool) error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetProjectId() string {
|
||||
return self.lb.GetProjectId()
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetListenerType() string {
|
||||
return self.Protocol
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetListenerPort() int {
|
||||
port, err := strconv.Atoi(self.Port)
|
||||
if err != nil {
|
||||
log.Errorf("GetListenerPort %s", err)
|
||||
return 0
|
||||
}
|
||||
|
||||
return port
|
||||
}
|
||||
|
||||
/*
|
||||
在本地范围内使用的负载均衡算法。可能的值为:
|
||||
|
||||
ROUND_ROBIN:这是一个简单的策略,其中按循环顺序选择每个健康的后端。这是默认设置。
|
||||
LEAST_REQUEST:一种 O(1) 算法,它选择两个随机的健康主机并选择具有较少活动请求的主机。
|
||||
RING_HASH:环/模散列负载均衡器对后端实现一致的散列。该算法的特性是从一组 N 个主机中添加/删除一个主机只会影响 1/N 的请求。
|
||||
RANDOM:负载均衡器随机选择一个健康的主机。
|
||||
ORIGINAL_DESTINATION:根据客户端连接元数据选择后端主机,即在连接被重定向到负载均衡器之前,连接被打开到与传入连接的目标地址相同的地址。
|
||||
MAGLEV:用作环形哈希负载均衡器的替代品。Maglev 不如环哈希稳定,但具有更快的表查找构建时间和主机选择时间。有关磁悬浮的更多信息,请参阅https://ai.google/research/pubs/pub44824
|
||||
此字段适用于:
|
||||
|
||||
service_protocol 设置为 HTTP、HTTPS 或 HTTP2,并且 load_balancing_scheme 设置为 INTERNAL_MANAGED 的区域后端服务。
|
||||
load_balancing_scheme 设置为 INTERNAL_SELF_MANAGED 的全局后端服务。
|
||||
如果 sessionAffinity 不为 NONE,并且该字段未设置为 MAGLEV 或 RING_HASH,则会话亲缘性设置不会生效。
|
||||
|
||||
当后端服务被绑定到目标 gRPC 代理且 validateForProxyless 字段设置为 true 的 URL 映射引用时,仅支持默认的 ROUND_ROBIN 策略。
|
||||
*/
|
||||
// todo: fix me ???
|
||||
func (self *SLoadbalancerListener) GetScheduler() string {
|
||||
switch self.backendService.LocalityLBPolicy {
|
||||
case "ROUND_ROBIN":
|
||||
return api.LB_SCHEDULER_RR
|
||||
case "LEAST_REQUEST":
|
||||
return api.LB_SCHEDULER_WLC
|
||||
case "RING_HASH":
|
||||
return api.LB_SCHEDULER_QCH
|
||||
case "ORIGINAL_DESTINATION":
|
||||
return api.LB_SCHEDULER_SCH
|
||||
case "MAGLEV":
|
||||
return api.LB_SCHEDULER_MH
|
||||
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) GetBackendGroupId() string {
|
||||
return self.backendService.GetGlobalId()
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetBackendServerPort() int {
|
||||
igs, err := self.GetInstanceGroups()
|
||||
if err != nil {
|
||||
log.Errorf("GetInstanceGroups %s", err)
|
||||
return 0
|
||||
}
|
||||
|
||||
for i := range igs {
|
||||
for j := range igs[i].NamedPorts {
|
||||
if igs[i].NamedPorts[j].Name == self.backendService.PortName {
|
||||
return int(igs[i].NamedPorts[j].Port)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetClientIdleTimeout() int {
|
||||
return int(self.backendService.ConnectionDraining.DrainingTimeoutSEC)
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetBackendConnectTimeout() int {
|
||||
return int(self.backendService.TimeoutSEC)
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) CreateILoadBalancerListenerRule(rule *cloudprovider.SLoadbalancerListenerRule) (cloudprovider.ICloudLoadbalancerListenerRule, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetILoadBalancerListenerRuleById(ruleId string) (cloudprovider.ICloudLoadbalancerListenerRule, error) {
|
||||
rules, err := self.GetLoadbalancerListenerRules()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetLoadbalancerListenerRules")
|
||||
}
|
||||
|
||||
for i := range rules {
|
||||
if rules[i].GetGlobalId() == ruleId {
|
||||
return &rules[i], nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetILoadbalancerListenerRules() ([]cloudprovider.ICloudLoadbalancerListenerRule, error) {
|
||||
rules, err := self.GetLoadbalancerListenerRules()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetLoadbalancerListenerRules")
|
||||
}
|
||||
|
||||
irules := make([]cloudprovider.ICloudLoadbalancerListenerRule, len(rules))
|
||||
for i := range rules {
|
||||
irules[i] = &rules[i]
|
||||
}
|
||||
|
||||
return irules, nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetStickySession() string {
|
||||
if self.backendService.SessionAffinity == "NONE" {
|
||||
return api.LB_BOOL_OFF
|
||||
} else {
|
||||
return api.LB_BOOL_ON
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
https://cloud.google.com/load-balancing/docs/backend-service#sessionAffinity
|
||||
区域级外部 HTTP(S) 负载均衡器:
|
||||
无 (NONE)
|
||||
客户端 IP (CLIENT_IP)
|
||||
生成的 Cookie (GENERATED_COOKIE)
|
||||
标头字段 (HEADER_FIELD)
|
||||
HTTP Cookie (HTTP_COOKIE)
|
||||
*/
|
||||
func (self *SLoadbalancerListener) GetStickySessionType() string {
|
||||
switch self.backendService.SessionAffinity {
|
||||
case "HTTP_COOKIE":
|
||||
return api.LB_STICKY_SESSION_TYPE_SERVER
|
||||
case "GENERATED_COOKIE":
|
||||
return api.LB_STICKY_SESSION_TYPE_INSERT
|
||||
}
|
||||
return self.backendService.SessionAffinity
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetStickySessionCookie() string {
|
||||
return self.backendService.ConsistentHash.HTTPCookie.Name
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetStickySessionCookieTimeout() int {
|
||||
sec, err := strconv.Atoi(self.backendService.ConsistentHash.HTTPCookie.TTL.Seconds)
|
||||
if err != nil {
|
||||
log.Debugf("GetStickySessionCookieTimeout %s", err)
|
||||
return 0
|
||||
}
|
||||
|
||||
return sec
|
||||
}
|
||||
|
||||
// https://cloud.google.com/load-balancing/docs/https
|
||||
func (self *SLoadbalancerListener) XForwardedForEnabled() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// https://cloud.google.com/load-balancing/docs/https/troubleshooting-ext-https-lbs
|
||||
func (self *SLoadbalancerListener) GzipEnabled() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetCertificateId() string {
|
||||
if self.httpsProxy != nil && len(self.httpsProxy.SSLCertificates) > 0 {
|
||||
cert := SResourceBase{
|
||||
Name: "",
|
||||
SelfLink: self.httpsProxy.SSLCertificates[0],
|
||||
}
|
||||
return cert.GetGlobalId()
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetTLSCipherPolicy() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// https://cloud.google.com/load-balancing/docs/https/troubleshooting-ext-https-lbs
|
||||
func (self *SLoadbalancerListener) HTTP2Enabled() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// todo: fix me route
|
||||
// 高级配置才有重定向,具体怎么解析?
|
||||
func (self *SLoadbalancerListener) GetRedirect() string {
|
||||
//self.lb.urlMap.PathMatchers[0].RouteRules[0].URLRedirect
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetRedirectCode() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetRedirectScheme() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetRedirectHost() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetRedirectPath() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetHealthCheck() string {
|
||||
if len(self.backendService.HealthChecks) > 0 {
|
||||
return api.LB_BOOL_ON
|
||||
} else {
|
||||
return api.LB_BOOL_OFF
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetHealthChecks() []HealthChecks {
|
||||
if self.healthChecks != nil {
|
||||
return self.healthChecks
|
||||
}
|
||||
|
||||
hcm, err := self.lb.GetHealthCheckMaps()
|
||||
if err != nil {
|
||||
log.Errorf("GetHealthCheckMaps %s", err)
|
||||
return nil
|
||||
}
|
||||
ret := make([]HealthChecks, 0)
|
||||
for i := range self.backendService.HealthChecks {
|
||||
hc := self.backendService.HealthChecks[i]
|
||||
if _, ok := hcm[hc]; ok {
|
||||
ret = append(ret, hcm[hc])
|
||||
}
|
||||
}
|
||||
|
||||
self.healthChecks = ret
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetHealthCheckType() string {
|
||||
hcs := self.GetHealthChecks()
|
||||
if hcs == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
switch strings.ToLower(hcs[0].Type) {
|
||||
case "tcp":
|
||||
return api.LB_HEALTH_CHECK_TCP
|
||||
case "udp":
|
||||
return api.LB_HEALTH_CHECK_UDP
|
||||
case "http", "http2":
|
||||
return api.LB_HEALTH_CHECK_HTTP
|
||||
case "https", "ssl":
|
||||
return api.LB_HEALTH_CHECK_HTTPS
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetHealthCheckTimeout() int {
|
||||
hcs := self.GetHealthChecks()
|
||||
if hcs == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return int(hcs[0].TimeoutSEC)
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetHealthCheckInterval() int {
|
||||
hcs := self.GetHealthChecks()
|
||||
if hcs == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return int(hcs[0].CheckIntervalSEC)
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetHealthCheckRise() int {
|
||||
hcs := self.GetHealthChecks()
|
||||
if hcs == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return int(hcs[0].HealthyThreshold)
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetHealthCheckFail() int {
|
||||
hcs := self.GetHealthChecks()
|
||||
if hcs == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return int(hcs[0].UnhealthyThreshold)
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetHealthCheckReq() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetHealthCheckExp() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetHealthCheckDomain() string {
|
||||
hcs := self.GetHealthChecks()
|
||||
if hcs == nil {
|
||||
return ""
|
||||
}
|
||||
switch hcs[0].Type {
|
||||
case "HTTPS":
|
||||
return hcs[0].HTTPSHealthCheck.Host
|
||||
case "HTTP2":
|
||||
return hcs[0].Http2HealthCheck.Host
|
||||
case "HTTP":
|
||||
return hcs[0].HTTPHealthCheck.Host
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetHealthCheckURI() string {
|
||||
hcs := self.GetHealthChecks()
|
||||
if hcs == nil {
|
||||
return ""
|
||||
}
|
||||
switch hcs[0].Type {
|
||||
case "HTTPS":
|
||||
return hcs[0].HTTPSHealthCheck.RequestPath
|
||||
case "HTTP2":
|
||||
return hcs[0].Http2HealthCheck.RequestPath
|
||||
case "HTTP":
|
||||
return hcs[0].HTTPHealthCheck.RequestPath
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetHealthCheckCode() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) Start() error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) Stop() error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) Sync(ctx context.Context, listener *cloudprovider.SLoadbalancerListener) error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) Delete(ctx context.Context) error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetInstanceGroups() ([]SInstanceGroup, error) {
|
||||
igs, err := self.lb.GetInstanceGroupsMap()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetInstanceGroups")
|
||||
}
|
||||
|
||||
ret := make([]SInstanceGroup, 0)
|
||||
for i := range self.backendService.Backends {
|
||||
b := self.backendService.Backends[i]
|
||||
if ig, ok := igs[b.Group]; ok {
|
||||
ret = append(ret, ig)
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetLoadbalancerListeners() ([]SLoadbalancerListener, error) {
|
||||
if self.urlMap != nil {
|
||||
return self.GetHTTPLoadbalancerListeners()
|
||||
} else {
|
||||
return self.GetNetworkLoadbalancerListeners()
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetHTTPLoadbalancerListeners() ([]SLoadbalancerListener, error) {
|
||||
frs, err := self.GetForwardingRules()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetForwardingRules")
|
||||
}
|
||||
|
||||
_hps, err := self.GetTargetHttpProxies()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetTargetHttpProxies")
|
||||
}
|
||||
|
||||
hps := make(map[string]STargetHttpProxy, 0)
|
||||
for i := range _hps {
|
||||
hps[_hps[i].SelfLink] = _hps[i]
|
||||
}
|
||||
|
||||
_hsps, err := self.GetTargetHttpsProxies()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetTargetHttpsProxies")
|
||||
}
|
||||
|
||||
hsps := make(map[string]STargetHttpsProxy, 0)
|
||||
for i := range _hsps {
|
||||
hsps[_hsps[i].SelfLink] = _hsps[i]
|
||||
}
|
||||
|
||||
bss, err := self.GetBackendServices()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetBackendServices")
|
||||
}
|
||||
|
||||
lbls := make([]SLoadbalancerListener, 0)
|
||||
for i := range frs {
|
||||
fr := frs[i]
|
||||
for j := range bss {
|
||||
bs := bss[j]
|
||||
port := "80"
|
||||
protocol := "http"
|
||||
var hp STargetHttpProxy
|
||||
var hsp STargetHttpsProxy
|
||||
if fr.PortRange == "443-443" {
|
||||
port = "443"
|
||||
hsp = hsps[fr.Target]
|
||||
protocol = "https"
|
||||
} else if fr.PortRange == "8080-8080" {
|
||||
port = "8080"
|
||||
hp = hps[fr.Target]
|
||||
} else {
|
||||
hp = hps[fr.Target]
|
||||
}
|
||||
|
||||
lbl := SLoadbalancerListener{
|
||||
lb: self,
|
||||
forwardRule: fr,
|
||||
backendService: bs,
|
||||
httpProxy: &hp,
|
||||
httpsProxy: &hsp,
|
||||
ForwardRuleName: fr.GetName(),
|
||||
BackendServiceName: bs.GetName(),
|
||||
Protocol: protocol,
|
||||
Port: port,
|
||||
}
|
||||
lbls = append(lbls, lbl)
|
||||
}
|
||||
}
|
||||
|
||||
return lbls, nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancer) GetNetworkLoadbalancerListeners() ([]SLoadbalancerListener, error) {
|
||||
frs, err := self.GetForwardingRules()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetForwardingRules")
|
||||
}
|
||||
|
||||
bss, err := self.GetBackendServices()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetBackendServices")
|
||||
}
|
||||
|
||||
lbls := make([]SLoadbalancerListener, 0)
|
||||
for i := range frs {
|
||||
fr := frs[i]
|
||||
for j := range bss {
|
||||
bs := bss[j]
|
||||
for n := range fr.Ports {
|
||||
lbl := SLoadbalancerListener{
|
||||
lb: self,
|
||||
forwardRule: fr,
|
||||
backendService: bs,
|
||||
ForwardRuleName: fr.GetName(),
|
||||
BackendServiceName: bs.GetName(),
|
||||
Protocol: strings.ToLower(fr.IPProtocol),
|
||||
Port: fr.Ports[n],
|
||||
}
|
||||
|
||||
lbls = append(lbls, lbl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return lbls, nil
|
||||
}
|
||||
163
pkg/multicloud/google/loadbalancer_listenerrule.go
Normal file
163
pkg/multicloud/google/loadbalancer_listenerrule.go
Normal file
@@ -0,0 +1,163 @@
|
||||
package google
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SLoadbalancerListenerRule struct {
|
||||
lbl *SLoadbalancerListener
|
||||
pathMatcher PathMatcher
|
||||
pathRule PathRule
|
||||
backendService SBackendServices
|
||||
|
||||
ListenerName string `json:"listener_name"`
|
||||
BackendServiceName string `json:"backend_service_name"`
|
||||
Domain string `json:"domain"`
|
||||
Path string `json:"path"`
|
||||
Port string `json:"Port"`
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerRule) GetId() string {
|
||||
return fmt.Sprintf("%s::%s::%s", self.lbl.GetGlobalId(), self.Domain, strings.Join(self.pathRule.Paths, ","))
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerRule) GetName() string {
|
||||
return fmt.Sprintf("%s::%s::%s", self.lbl.GetName(), self.Domain, strings.Join(self.pathRule.Paths, ","))
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerRule) GetGlobalId() string {
|
||||
return self.GetId()
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerRule) GetStatus() string {
|
||||
return api.LB_STATUS_ENABLED
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerRule) Refresh() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerRule) IsEmulated() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
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 cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerRule) GetProjectId() string {
|
||||
return self.lbl.GetProjectId()
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerRule) GetRedirect() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerRule) GetRedirectCode() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerRule) GetRedirectScheme() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerRule) GetRedirectHost() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerRule) GetRedirectPath() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerRule) IsDefault() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerRule) GetDomain() string {
|
||||
return self.Domain
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerRule) GetPath() string {
|
||||
return self.Path
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerRule) GetCondition() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerRule) GetBackendGroupId() string {
|
||||
return self.backendService.GetGlobalId()
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerRule) Delete(ctx context.Context) error {
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListener) GetLoadbalancerListenerRules() ([]SLoadbalancerListenerRule, error) {
|
||||
if !self.lb.isHttpLb {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if self.rules != nil {
|
||||
return self.rules, nil
|
||||
}
|
||||
|
||||
hostRules := self.lb.urlMap.HostRules
|
||||
pathMatchers := self.lb.urlMap.PathMatchers
|
||||
|
||||
pmm := make(map[string]PathMatcher, 0)
|
||||
for i := range pathMatchers {
|
||||
name := pathMatchers[i].Name
|
||||
pmm[name] = pathMatchers[i]
|
||||
}
|
||||
|
||||
ret := make([]SLoadbalancerListenerRule, 0)
|
||||
for _, rule := range hostRules {
|
||||
pm, ok := pmm[rule.PathMatcher]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
for i := range rule.Hosts {
|
||||
host := rule.Hosts[i]
|
||||
for j := range pm.PathRules {
|
||||
pr := pm.PathRules[j]
|
||||
|
||||
if pr.Service != self.backendService.GetId() {
|
||||
continue
|
||||
}
|
||||
|
||||
r := SLoadbalancerListenerRule{
|
||||
lbl: self,
|
||||
backendService: self.backendService,
|
||||
BackendServiceName: self.backendService.GetName(),
|
||||
pathMatcher: pm,
|
||||
pathRule: pr,
|
||||
|
||||
ListenerName: self.GetName(),
|
||||
Domain: host,
|
||||
Path: strings.Join(pr.Paths, ","),
|
||||
Port: self.Port,
|
||||
}
|
||||
|
||||
ret = append(ret, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.rules = ret
|
||||
return ret, nil
|
||||
}
|
||||
@@ -500,7 +500,11 @@ func (region *SRegion) BillingListAll(resource string, params map[string]string,
|
||||
}
|
||||
|
||||
func (region *SRegion) ListAll(resource string, params map[string]string, retval interface{}) error {
|
||||
return region.client.ecsListAll(resource, params, retval)
|
||||
return region.listAll("GET", resource, params, retval)
|
||||
}
|
||||
|
||||
func (region *SRegion) listAll(method string, resource string, params map[string]string, retval interface{}) error {
|
||||
return region.client._ecsListAll(method, resource, params, retval)
|
||||
}
|
||||
|
||||
func (region *SRegion) List(resource string, params map[string]string, maxResults int, pageToken string, retval interface{}) error {
|
||||
|
||||
214
pkg/multicloud/google/shell/loadbalancer.go
Normal file
214
pkg/multicloud/google/shell/loadbalancer.go
Normal file
@@ -0,0 +1,214 @@
|
||||
// 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 shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/multicloud/google"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type ElbListOptions struct {
|
||||
}
|
||||
shellutils.R(&ElbListOptions{}, "lb-list", "List loadbalancers", func(cli *google.SRegion, args *ElbListOptions) error {
|
||||
elbs, err := cli.GetRegionalLoadbalancers()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printList(elbs, len(elbs), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
|
||||
type ElbShowOptions struct {
|
||||
RESOURCEID string `json:"resourceid"`
|
||||
}
|
||||
shellutils.R(&ElbShowOptions{}, "lb-bss", "List all loadbalancer backend services", func(cli *google.SRegion, args *ElbShowOptions) error {
|
||||
lb, err := cli.GetLoadbalancer(args.RESOURCEID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
elbs, err := lb.GetBackendServices()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printList(elbs, len(elbs), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
|
||||
shellutils.R(&ElbShowOptions{}, "lb-frs", "List all loadbalancer forward rules", func(cli *google.SRegion, args *ElbShowOptions) error {
|
||||
lb, err := cli.GetLoadbalancer(args.RESOURCEID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
elbs, err := lb.GetForwardingRules()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printList(elbs, len(elbs), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
|
||||
shellutils.R(&ElbShowOptions{}, "lb-http", "List loadbalancer https proxies", func(cli *google.SRegion, args *ElbShowOptions) error {
|
||||
elb, err := cli.GetLoadbalancer(args.RESOURCEID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hps, e := elb.GetTargetHttpProxies()
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printList(hps, len(hps), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
|
||||
shellutils.R(&ElbShowOptions{}, "lb-https", "List loadbalancer https proxies", func(cli *google.SRegion, args *ElbShowOptions) error {
|
||||
elb, err := cli.GetLoadbalancer(args.RESOURCEID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hps, e := elb.GetTargetHttpsProxies()
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printList(hps, len(hps), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
|
||||
shellutils.R(&ElbShowOptions{}, "lb-igs", "List all loadbalancer instance groups", func(cli *google.SRegion, args *ElbShowOptions) error {
|
||||
elb, err := cli.GetLoadbalancer(args.RESOURCEID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hps, e := elb.GetInstanceGroups()
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printList(hps, len(hps), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
|
||||
shellutils.R(&ElbShowOptions{}, "lbl-list", "List all loadbalancer listeners", func(cli *google.SRegion, args *ElbShowOptions) error {
|
||||
elb, err := cli.GetLoadbalancer(args.RESOURCEID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hps, e := elb.GetLoadbalancerListeners()
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printList(hps, len(hps), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
|
||||
shellutils.R(&ElbShowOptions{}, "lblr-list", "List all loadbalancer listener rules", func(cli *google.SRegion, args *ElbShowOptions) error {
|
||||
elb, err := cli.GetLoadbalancer(args.RESOURCEID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hps, e := elb.GetLoadbalancerListeners()
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
rules := make([]google.SLoadbalancerListenerRule, 0)
|
||||
|
||||
for i := range hps {
|
||||
_rules, ee := hps[i].GetLoadbalancerListenerRules()
|
||||
if e != nil {
|
||||
return ee
|
||||
}
|
||||
|
||||
rules = append(rules, _rules...)
|
||||
}
|
||||
|
||||
printList(rules, len(rules), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
|
||||
shellutils.R(&ElbShowOptions{}, "lbbg-list", "List all loadbalancer backendgroups", func(cli *google.SRegion, args *ElbShowOptions) error {
|
||||
lb, err := cli.GetLoadbalancer(args.RESOURCEID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lbbg, e := lb.GetLoadbalancerBackendGroups()
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
printList(lbbg, len(lbbg), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
|
||||
shellutils.R(&ElbShowOptions{}, "lbb-list", "List all loadbalancer backends", func(cli *google.SRegion, args *ElbShowOptions) error {
|
||||
lb, err := cli.GetLoadbalancer(args.RESOURCEID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lbbg, e := lb.GetLoadbalancerBackendGroups()
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
lbbs := make([]google.SLoadbalancerBackend, 0)
|
||||
for i := range lbbg {
|
||||
backends, err := lbbg[i].GetLoadbalancerBackends()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lbbs = append(lbbs, backends...)
|
||||
}
|
||||
|
||||
printList(lbbs, len(lbbs), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
|
||||
shellutils.R(&ElbShowOptions{}, "lbhc-list", "List all loadbalancer health checks", func(cli *google.SRegion, args *ElbShowOptions) error {
|
||||
lb, err := cli.GetLoadbalancer(args.RESOURCEID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hcs, e := lb.GetHealthChecks()
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
printList(hcs, len(hcs), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
|
||||
shellutils.R(&ElbListOptions{}, "cert-list", "List region certificates", func(cli *google.SRegion, args *ElbListOptions) error {
|
||||
certs, err := cli.GetRegionalSslCertificates("")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printList(certs, len(certs), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user