support gcp regional lb sync

This commit is contained in:
tb365
2021-10-27 09:14:29 +08:00
parent acaba56c88
commit 5b573b66ea
11 changed files with 2610 additions and 4 deletions

View File

@@ -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(

View File

@@ -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,

View 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
}

View 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
}

View 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
}

View 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
}

View 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
}

View 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
}

View 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
}

View File

@@ -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 {

View 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
})
}