yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/google/loadbalancer_components.go (about)

     1  // Copyright 2019 Yunion
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package google
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  
    21  	"yunion.io/x/pkg/errors"
    22  	"yunion.io/x/pkg/utils"
    23  
    24  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    25  )
    26  
    27  type SUrlMap struct {
    28  	SResourceBase
    29  
    30  	CreationTimestamp string        `json:"creationTimestamp"`
    31  	HostRules         []HostRule    `json:"hostRules"`
    32  	PathMatchers      []PathMatcher `json:"pathMatchers"`
    33  	DefaultService    string        `json:"defaultService"`
    34  	Fingerprint       string        `json:"fingerprint"`
    35  	Region            string        `json:"region"`
    36  	Kind              string        `json:"kind"`
    37  }
    38  
    39  type SForwardingRule struct {
    40  	SResourceBase
    41  
    42  	CreationTimestamp   string   `json:"creationTimestamp"`
    43  	Description         string   `json:"description"`
    44  	Region              string   `json:"region"`
    45  	IPAddress           string   `json:"IPAddress"`
    46  	IPProtocol          string   `json:"IPProtocol"`
    47  	PortRange           string   `json:"portRange"`
    48  	Target              string   `json:"target"`
    49  	LoadBalancingScheme string   `json:"loadBalancingScheme"`
    50  	Subnetwork          string   `json:"subnetwork"`
    51  	Network             string   `json:"network"`
    52  	NetworkTier         string   `json:"networkTier"`
    53  	LabelFingerprint    string   `json:"labelFingerprint"`
    54  	Fingerprint         string   `json:"fingerprint"`
    55  	Kind                string   `json:"kind"`
    56  	Ports               []string `json:"ports"`
    57  	BackendService      string   `json:"backendService"`
    58  }
    59  
    60  //
    61  //type STargetProxy struct {
    62  //}
    63  //
    64  type SBackendServices struct {
    65  	SResourceBase
    66  
    67  	CreationTimestamp    string             `json:"creationTimestamp"`
    68  	Description          string             `json:"description"`
    69  	Backends             []Backend          `json:"backends"`
    70  	HealthChecks         []string           `json:"healthChecks"`
    71  	TimeoutSEC           int64              `json:"timeoutSec"`
    72  	Port                 int64              `json:"port"`
    73  	Protocol             string             `json:"protocol"`
    74  	Fingerprint          string             `json:"fingerprint"`
    75  	PortName             string             `json:"portName"`
    76  	SessionAffinity      string             `json:"sessionAffinity"`
    77  	AffinityCookieTTLSEC int64              `json:"affinityCookieTtlSec"`
    78  	Region               string             `json:"region"`
    79  	LoadBalancingScheme  string             `json:"loadBalancingScheme"`
    80  	ConnectionDraining   ConnectionDraining `json:"connectionDraining"`
    81  	LocalityLBPolicy     string             `json:"localityLbPolicy"`
    82  	ConsistentHash       ConsistentHash     `json:"consistentHash"`
    83  	Kind                 string             `json:"kind"`
    84  	EnableCDN            bool               `json:"enableCDN"`
    85  	Network              string             `json:"network"`
    86  }
    87  
    88  //
    89  //type STargetPool struct {
    90  //}
    91  
    92  type STargetHttpProxy struct {
    93  	SResourceBase
    94  
    95  	CreationTimestamp string `json:"creationTimestamp"`
    96  	Description       string `json:"description"`
    97  	URLMap            string `json:"urlMap"`
    98  	Region            string `json:"region"`
    99  	ProxyBind         bool   `json:"proxyBind"`
   100  	Fingerprint       string `json:"fingerprint"`
   101  	Kind              string `json:"kind"`
   102  }
   103  
   104  type STargetHttpsProxy struct {
   105  	SResourceBase
   106  
   107  	CreationTimestamp   string   `json:"creationTimestamp"`
   108  	Description         string   `json:"description"`
   109  	URLMap              string   `json:"urlMap"`
   110  	SSLCertificates     []string `json:"sslCertificates"`
   111  	QuicOverride        string   `json:"quicOverride"`
   112  	SSLPolicy           string   `json:"sslPolicy"`
   113  	Region              string   `json:"region"`
   114  	ProxyBind           bool     `json:"proxyBind"`
   115  	ServerTLSPolicy     string   `json:"serverTlsPolicy"`
   116  	AuthorizationPolicy string   `json:"authorizationPolicy"`
   117  	Fingerprint         string   `json:"fingerprint"`
   118  	Kind                string   `json:"kind"`
   119  }
   120  
   121  type SInstanceGroup struct {
   122  	SResourceBase
   123  	region    *SRegion
   124  	instances []SInstanceGroupInstance
   125  
   126  	CreationTimestamp string      `json:"creationTimestamp"`
   127  	Description       string      `json:"description"`
   128  	NamedPorts        []NamedPort `json:"namedPorts"`
   129  	Network           string      `json:"network"`
   130  	Fingerprint       string      `json:"fingerprint"`
   131  	Zone              string      `json:"zone"`
   132  	Size              int64       `json:"size"`
   133  	Region            string      `json:"region"`
   134  	Subnetwork        string      `json:"subnetwork"`
   135  	Kind              string      `json:"kind"`
   136  }
   137  
   138  type SInstanceGroupInstance struct {
   139  	instanceGroup *SInstanceGroup
   140  	Instance      string      `json:"instance"`
   141  	Status        string      `json:"status"`
   142  	NamedPorts    []NamedPort `json:"namedPorts"`
   143  }
   144  
   145  type NamedPort struct {
   146  	Name string `json:"name"`
   147  	Port int64  `json:"port"`
   148  }
   149  
   150  type ConsistentHash struct {
   151  	HTTPCookie      HTTPCookie `json:"httpCookie"`
   152  	MinimumRingSize string     `json:"minimumRingSize"`
   153  }
   154  
   155  type HTTPCookie struct {
   156  	Name string `json:"name"`
   157  	Path string `json:"path"`
   158  	TTL  TTL    `json:"ttl"`
   159  }
   160  
   161  type TTL struct {
   162  	Seconds string `json:"seconds"`
   163  	Nanos   int64  `json:"nanos"`
   164  }
   165  
   166  type RouteAction struct {
   167  	WeightedBackendServices []WeightedBackendService `json:"weightedBackendServices"`
   168  	URLRewrite              URLRewrite               `json:"urlRewrite"`
   169  	Timeout                 MaxStreamDuration        `json:"timeout"`
   170  	RetryPolicy             RetryPolicy              `json:"retryPolicy"`
   171  	RequestMirrorPolicy     RequestMirrorPolicy      `json:"requestMirrorPolicy"`
   172  	CorsPolicy              CorsPolicy               `json:"corsPolicy"`
   173  	FaultInjectionPolicy    FaultInjectionPolicy     `json:"faultInjectionPolicy"`
   174  	MaxStreamDuration       MaxStreamDuration        `json:"maxStreamDuration"`
   175  }
   176  
   177  type CorsPolicy struct {
   178  	AllowOrigins       []string `json:"allowOrigins"`
   179  	AllowOriginRegexes []string `json:"allowOriginRegexes"`
   180  	AllowMethods       []string `json:"allowMethods"`
   181  	AllowHeaders       []string `json:"allowHeaders"`
   182  	ExposeHeaders      []string `json:"exposeHeaders"`
   183  	MaxAge             int64    `json:"maxAge"`
   184  	AllowCredentials   bool     `json:"allowCredentials"`
   185  	Disabled           bool     `json:"disabled"`
   186  }
   187  
   188  type FaultInjectionPolicy struct {
   189  	Delay Delay `json:"delay"`
   190  	Abort Abort `json:"abort"`
   191  }
   192  
   193  type Abort struct {
   194  	HTTPStatus int64   `json:"httpStatus"`
   195  	Percentage float64 `json:"percentage"`
   196  }
   197  
   198  type Delay struct {
   199  	FixedDelay MaxStreamDuration `json:"fixedDelay"`
   200  	Percentage float64           `json:"percentage"`
   201  }
   202  
   203  type MaxStreamDuration struct {
   204  	Seconds string `json:"seconds"`
   205  	Nanos   int64  `json:"nanos"`
   206  }
   207  
   208  type RequestMirrorPolicy struct {
   209  	BackendService string `json:"backendService"`
   210  }
   211  
   212  type RetryPolicy struct {
   213  	RetryConditions []string          `json:"retryConditions"`
   214  	NumRetries      int64             `json:"numRetries"`
   215  	PerTryTimeout   MaxStreamDuration `json:"perTryTimeout"`
   216  }
   217  
   218  type URLRewrite struct {
   219  	PathPrefixRewrite string `json:"pathPrefixRewrite"`
   220  	HostRewrite       string `json:"hostRewrite"`
   221  }
   222  
   223  type WeightedBackendService struct {
   224  	BackendService string       `json:"backendService"`
   225  	Weight         int64        `json:"weight"`
   226  	HeaderAction   HeaderAction `json:"headerAction"`
   227  }
   228  
   229  type HeaderAction struct {
   230  	RequestHeadersToRemove  []string       `json:"requestHeadersToRemove"`
   231  	RequestHeadersToAdd     []HeadersToAdd `json:"requestHeadersToAdd"`
   232  	ResponseHeadersToRemove []string       `json:"responseHeadersToRemove"`
   233  	ResponseHeadersToAdd    []HeadersToAdd `json:"responseHeadersToAdd"`
   234  }
   235  
   236  type HeadersToAdd struct {
   237  	HeaderName  string `json:"headerName"`
   238  	HeaderValue string `json:"headerValue"`
   239  	Replace     bool   `json:"replace"`
   240  }
   241  
   242  type URLRedirect struct {
   243  	HostRedirect         string `json:"hostRedirect"`
   244  	PathRedirect         string `json:"pathRedirect"`
   245  	PrefixRedirect       string `json:"prefixRedirect"`
   246  	RedirectResponseCode string `json:"redirectResponseCode"`
   247  	HTTPSRedirect        bool   `json:"httpsRedirect"`
   248  	StripQuery           bool   `json:"stripQuery"`
   249  }
   250  
   251  type HostRule struct {
   252  	Description string   `json:"description"`
   253  	Hosts       []string `json:"hosts"`
   254  	PathMatcher string   `json:"pathMatcher"`
   255  }
   256  
   257  type PathMatcher struct {
   258  	Name               string       `json:"name"`
   259  	Description        string       `json:"description"`
   260  	DefaultService     string       `json:"defaultService"`
   261  	DefaultRouteAction RouteAction  `json:"defaultRouteAction"`
   262  	DefaultURLRedirect URLRedirect  `json:"defaultUrlRedirect"`
   263  	PathRules          []PathRule   `json:"pathRules"`
   264  	RouteRules         []RouteRule  `json:"routeRules"`
   265  	HeaderAction       HeaderAction `json:"headerAction"`
   266  }
   267  
   268  type PathRule struct {
   269  	Service     string      `json:"service"`
   270  	RouteAction RouteAction `json:"routeAction"`
   271  	URLRedirect URLRedirect `json:"urlRedirect"`
   272  	Paths       []string    `json:"paths"`
   273  }
   274  
   275  type RouteRule struct {
   276  	Priority     int64        `json:"priority"`
   277  	Description  string       `json:"description"`
   278  	MatchRules   []MatchRule  `json:"matchRules"`
   279  	Service      string       `json:"service"`
   280  	RouteAction  RouteAction  `json:"routeAction"`
   281  	URLRedirect  URLRedirect  `json:"urlRedirect"`
   282  	HeaderAction HeaderAction `json:"headerAction"`
   283  }
   284  
   285  type MatchRule struct {
   286  	PrefixMatch           string                `json:"prefixMatch"`
   287  	FullPathMatch         string                `json:"fullPathMatch"`
   288  	RegexMatch            string                `json:"regexMatch"`
   289  	IgnoreCase            bool                  `json:"ignoreCase"`
   290  	HeaderMatches         []HeaderMatch         `json:"headerMatches"`
   291  	QueryParameterMatches []QueryParameterMatch `json:"queryParameterMatches"`
   292  	MetadataFilters       []MetadataFilter      `json:"metadataFilters"`
   293  }
   294  
   295  type HeaderMatch struct {
   296  	HeaderName   string     `json:"headerName"`
   297  	ExactMatch   string     `json:"exactMatch"`
   298  	RegexMatch   string     `json:"regexMatch"`
   299  	RangeMatch   RangeMatch `json:"rangeMatch"`
   300  	PresentMatch bool       `json:"presentMatch"`
   301  	PrefixMatch  string     `json:"prefixMatch"`
   302  	SuffixMatch  string     `json:"suffixMatch"`
   303  	InvertMatch  bool       `json:"invertMatch"`
   304  }
   305  
   306  type RangeMatch struct {
   307  	RangeStart string `json:"rangeStart"`
   308  	RangeEnd   string `json:"rangeEnd"`
   309  }
   310  
   311  type MetadataFilter struct {
   312  	FilterMatchCriteria string   `json:"filterMatchCriteria"`
   313  	FilterLabels        []Header `json:"filterLabels"`
   314  }
   315  
   316  type Header struct {
   317  	Name  string `json:"name"`
   318  	Value string `json:"value"`
   319  }
   320  
   321  type QueryParameterMatch struct {
   322  	Name         string `json:"name"`
   323  	PresentMatch bool   `json:"presentMatch"`
   324  	ExactMatch   string `json:"exactMatch"`
   325  	RegexMatch   string `json:"regexMatch"`
   326  }
   327  
   328  type Test struct {
   329  	Description                  string   `json:"description"`
   330  	Host                         string   `json:"host"`
   331  	Path                         string   `json:"path"`
   332  	Headers                      []Header `json:"headers"`
   333  	Service                      string   `json:"service"`
   334  	ExpectedOutputURL            string   `json:"expectedOutputUrl"`
   335  	ExpectedRedirectResponseCode int64    `json:"expectedRedirectResponseCode"`
   336  }
   337  
   338  type Backend struct {
   339  	Group         string `json:"group"`
   340  	BalancingMode string `json:"balancingMode"`
   341  	Failover      bool   `json:"failover"`
   342  }
   343  
   344  type ConnectionDraining struct {
   345  	DrainingTimeoutSEC int64 `json:"drainingTimeoutSec"`
   346  }
   347  
   348  type HealthChecks struct {
   349  	SResourceBase
   350  
   351  	CreationTimestamp  string          `json:"creationTimestamp"`
   352  	Description        string          `json:"description"`
   353  	CheckIntervalSEC   int64           `json:"checkIntervalSec"`
   354  	TimeoutSEC         int64           `json:"timeoutSec"`
   355  	UnhealthyThreshold int64           `json:"unhealthyThreshold"`
   356  	HealthyThreshold   int64           `json:"healthyThreshold"`
   357  	Type               string          `json:"type"`
   358  	HTTPSHealthCheck   HTTPHealthCheck `json:"httpsHealthCheck"`
   359  	Region             string          `json:"region"`
   360  	Kind               string          `json:"kind"`
   361  	Http2HealthCheck   HTTPHealthCheck `json:"http2HealthCheck"`
   362  	TCPHealthCheck     TCPHealthCheck  `json:"tcpHealthCheck"`
   363  	SSLHealthCheck     SSLHealthCheck  `json:"sslHealthCheck"`
   364  	HTTPHealthCheck    HTTPHealthCheck `json:"httpHealthCheck"`
   365  }
   366  
   367  type HTTPHealthCheck struct {
   368  	Port        int64  `json:"port"`
   369  	Host        string `json:"host"`
   370  	RequestPath string `json:"requestPath"`
   371  	ProxyHeader string `json:"proxyHeader"`
   372  	Response    string `json:"response"`
   373  }
   374  
   375  type SSLHealthCheck struct {
   376  	Port        int64  `json:"port"`
   377  	Request     string `json:"request"`
   378  	Response    string `json:"response"`
   379  	ProxyHeader string `json:"proxyHeader"`
   380  }
   381  
   382  type TCPHealthCheck struct {
   383  	Port        int64  `json:"port"`
   384  	ProxyHeader string `json:"proxyHeader"`
   385  }
   386  
   387  type LogConfig struct {
   388  	Enable bool `json:"enable"`
   389  }
   390  
   391  func (self *SInstanceGroup) GetInstances() ([]SInstanceGroupInstance, error) {
   392  	if self.instances != nil {
   393  		return self.instances, nil
   394  	}
   395  
   396  	ret := make([]SInstanceGroupInstance, 0)
   397  	resourceId := strings.Replace(self.GetGlobalId(), fmt.Sprintf("projects/%s/", self.region.GetProjectId()), "", -1)
   398  	err := self.region.listAll("POST", resourceId+"/listInstances", nil, &ret)
   399  	if err != nil {
   400  		if errors.Cause(err) == cloudprovider.ErrNotFound {
   401  			return nil, nil
   402  		}
   403  
   404  		return nil, errors.Wrap(err, "ListAll")
   405  	}
   406  
   407  	for i := range ret {
   408  		ret[i].instanceGroup = self
   409  	}
   410  
   411  	self.instances = ret
   412  	return ret, nil
   413  }
   414  
   415  func (self *SRegion) getLoadbalancerComponents(resource string, filter string, result interface{}) error {
   416  	url := fmt.Sprintf("regions/%s/%s", self.Name, resource)
   417  	params := map[string]string{}
   418  	if len(filter) > 0 {
   419  		params["filter"] = filter
   420  	}
   421  
   422  	err := self.ListAll(url, params, result)
   423  	if err != nil {
   424  		return errors.Wrap(err, "ListAll")
   425  	}
   426  
   427  	return nil
   428  }
   429  
   430  func (self *SRegion) getInstanceGroups(zoneId, resource string, filter string, result interface{}) error {
   431  	url := fmt.Sprintf("zones/%s/%s", zoneId, resource)
   432  	params := map[string]string{}
   433  	if len(filter) > 0 {
   434  		params["filter"] = filter
   435  	}
   436  
   437  	err := self.ListAll(url, params, result)
   438  	if err != nil {
   439  		return errors.Wrap(err, "ListAll")
   440  	}
   441  
   442  	return nil
   443  }
   444  
   445  /*
   446  As mentioned by Patrick W, there is no direct entity 'load balancer', its just a collection of components.
   447  The list seen in the UI that appears to be the load balancer is actually the url-map component,
   448  which can be seen via the API with:
   449  gcloud compute url-maps list
   450  */
   451  func (self *SRegion) GetRegionalUrlMaps(filter string) ([]SUrlMap, error) {
   452  	ret := make([]SUrlMap, 0)
   453  	err := self.getLoadbalancerComponents("urlMaps", filter, &ret)
   454  	return ret, err
   455  }
   456  
   457  func (self *SRegion) GetRegionalBackendServices(filter string) ([]SBackendServices, error) {
   458  	ret := make([]SBackendServices, 0)
   459  	err := self.getLoadbalancerComponents("backendServices", filter, &ret)
   460  	return ret, err
   461  }
   462  
   463  func (self *SRegion) GetRegionalForwardingRule(filter string) ([]SForwardingRule, error) {
   464  	ret := make([]SForwardingRule, 0)
   465  	err := self.getLoadbalancerComponents("forwardingRules", filter, &ret)
   466  	return ret, err
   467  }
   468  
   469  func (self *SRegion) GetRegionalTargetHttpProxies(filter string) ([]STargetHttpProxy, error) {
   470  	ret := make([]STargetHttpProxy, 0)
   471  	err := self.getLoadbalancerComponents("targetHttpProxies", filter, &ret)
   472  	return ret, err
   473  }
   474  
   475  func (self *SRegion) GetRegionalTargetHttpsProxies(filter string) ([]STargetHttpsProxy, error) {
   476  	ret := make([]STargetHttpsProxy, 0)
   477  	err := self.getLoadbalancerComponents("targetHttpsProxies", filter, &ret)
   478  	return ret, err
   479  }
   480  
   481  func (self *SRegion) GetRegionalInstanceGroups(filter string) ([]SInstanceGroup, error) {
   482  	ret := make([]SInstanceGroup, 0)
   483  	err := self.getLoadbalancerComponents("instanceGroups", filter, &ret)
   484  	for i := range ret {
   485  		ret[i].region = self
   486  	}
   487  	return ret, err
   488  }
   489  
   490  func (self *SRegion) GetRegionalHealthChecks(filter string) ([]HealthChecks, error) {
   491  	ret := make([]HealthChecks, 0)
   492  	err := self.getLoadbalancerComponents("healthChecks", filter, &ret)
   493  	return ret, err
   494  }
   495  
   496  func (self *SRegion) GetGlobalHealthChecks(filter string) ([]HealthChecks, error) {
   497  	ret := make([]HealthChecks, 0)
   498  	params := map[string]string{}
   499  	if len(filter) > 0 {
   500  		params["filter"] = filter
   501  	}
   502  
   503  	err := self.ListAll("global/healthChecks", params, &ret)
   504  	if err != nil {
   505  		return nil, errors.Wrap(err, "ListAll")
   506  	}
   507  
   508  	return ret, err
   509  }
   510  
   511  func (self *SRegion) GetRegionalSslCertificates(filter string) ([]SLoadbalancerCertificate, error) {
   512  	ret := make([]SLoadbalancerCertificate, 0)
   513  	err := self.getLoadbalancerComponents("sslCertificates", filter, &ret)
   514  	for i := range ret {
   515  		ret[i].region = self
   516  	}
   517  	return ret, err
   518  }
   519  
   520  func (self *SLoadbalancer) GetTargetHttpsProxies() ([]STargetHttpsProxy, error) {
   521  	ret := make([]STargetHttpsProxy, 0)
   522  	filter := fmt.Sprintf("urlMap eq %s", self.GetId())
   523  	err := self.region.getLoadbalancerComponents("targetHttpsProxies", filter, &ret)
   524  	return ret, err
   525  }
   526  
   527  func (self *SLoadbalancer) GetTargetHttpProxies() ([]STargetHttpProxy, error) {
   528  	ret := make([]STargetHttpProxy, 0)
   529  	filter := fmt.Sprintf("urlMap eq %s", self.GetId())
   530  	err := self.region.getLoadbalancerComponents("targetHttpProxies", filter, &ret)
   531  	return ret, err
   532  }
   533  
   534  // ForwardingRule 目标是: target proxy or backend service
   535  // http&https 是由target proxy 转发到后端服务
   536  func (self *SLoadbalancer) GetForwardingRules() ([]SForwardingRule, error) {
   537  	if self.forwardRules != nil {
   538  		return self.forwardRules, nil
   539  	}
   540  
   541  	hps, err := self.GetTargetHttpProxies()
   542  	if err != nil {
   543  		return nil, errors.Wrap(err, "GetTargetHttpProxies")
   544  	}
   545  
   546  	hsps, err := self.GetTargetHttpsProxies()
   547  	if err != nil {
   548  		return nil, errors.Wrap(err, "GetTargetHttpsProxies")
   549  	}
   550  
   551  	targets := make([]string, 0)
   552  	for i := range hps {
   553  		targets = append(targets, fmt.Sprintf(`(target="%s")`, hps[i].GetId()))
   554  	}
   555  
   556  	for i := range hsps {
   557  		targets = append(targets, fmt.Sprintf(`(target="%s")`, hsps[i].GetId()))
   558  	}
   559  
   560  	if strings.Contains(self.GetId(), "/backendServices/") {
   561  		targets = append(targets, fmt.Sprintf(`(backendService="%s")`, self.GetId()))
   562  	}
   563  
   564  	if len(targets) == 0 {
   565  		return []SForwardingRule{}, nil
   566  	}
   567  
   568  	filter := strings.Join(targets, " OR ")
   569  	ret := make([]SForwardingRule, 0)
   570  	err = self.region.getLoadbalancerComponents("forwardingRules", filter, &ret)
   571  	if err != nil {
   572  		return nil, errors.Wrap(err, "GetForwardingRules")
   573  	}
   574  
   575  	if len(ret) > 0 {
   576  		self.forwardRules = ret
   577  	}
   578  	return ret, nil
   579  }
   580  
   581  func (self *SLoadbalancer) GetBackendServices() ([]SBackendServices, error) {
   582  	if self.isHttpLb && self.urlMap != nil {
   583  		ret := make([]SBackendServices, 0)
   584  		ids := []string{self.urlMap.DefaultService}
   585  		for i := range self.urlMap.PathMatchers {
   586  			ps := self.urlMap.PathMatchers[i]
   587  			if len(ps.DefaultService) > 0 && !utils.IsInStringArray(ps.DefaultService, ids) {
   588  				ids = append(ids, ps.DefaultService)
   589  			}
   590  
   591  			for j := range ps.PathRules {
   592  				if len(ps.PathRules[j].Service) > 0 && !utils.IsInStringArray(ps.PathRules[j].Service, ids) {
   593  					ids = append(ids, ps.PathRules[j].Service)
   594  				}
   595  			}
   596  		}
   597  
   598  		filters := []string{}
   599  		for i := range ids {
   600  			filters = append(filters, fmt.Sprintf(`(selfLink="%s")`, ids[i]))
   601  		}
   602  
   603  		if len(filters) == 0 {
   604  			return []SBackendServices{}, nil
   605  		}
   606  		err := self.region.getLoadbalancerComponents("backendServices", strings.Join(filters, " OR "), &ret)
   607  		self.backendServices = ret
   608  		return ret, err
   609  	}
   610  
   611  	return self.backendServices, nil
   612  }
   613  
   614  func (self *SLoadbalancer) GetInstanceGroupsMap() (map[string]SInstanceGroup, error) {
   615  	igs, err := self.GetInstanceGroups()
   616  	if err != nil {
   617  		return nil, errors.Wrap(err, "GetInstanceGroups")
   618  	}
   619  
   620  	ret := make(map[string]SInstanceGroup, 0)
   621  	for i := range igs {
   622  		ig := igs[i]
   623  		ig.region = self.region
   624  		ret[ig.SelfLink] = ig
   625  	}
   626  
   627  	return ret, nil
   628  }
   629  
   630  func (self *SLoadbalancer) GetInstanceGroups() ([]SInstanceGroup, error) {
   631  	if self.instanceGroups != nil {
   632  		return self.instanceGroups, nil
   633  	}
   634  
   635  	if self.backendServices == nil {
   636  		bss, err := self.GetBackendServices()
   637  		if err != nil {
   638  			return nil, errors.Wrap(err, "GetBackendServices")
   639  		}
   640  		self.backendServices = bss
   641  	}
   642  
   643  	bgs := []string{}
   644  	for i := range self.backendServices {
   645  		_bgs := self.backendServices[i].Backends
   646  		for j := range _bgs {
   647  			if !utils.IsInStringArray(_bgs[j].Group, bgs) {
   648  				bgs = append(bgs, _bgs[j].Group)
   649  			}
   650  		}
   651  	}
   652  
   653  	if len(bgs) == 0 {
   654  		return []SInstanceGroup{}, nil
   655  	}
   656  
   657  	regionFilters := []string{}
   658  	zonesFilter := map[string][]string{}
   659  	for i := range bgs {
   660  		if !strings.Contains(bgs[i], "/zones/") {
   661  			regionFilters = append(regionFilters, fmt.Sprintf(`(selfLink="%s")`, bgs[i]))
   662  		} else {
   663  			ig := bgs[i]
   664  			index := strings.Index(ig, "/zones/")
   665  			zoneId := strings.Split(ig[index:], "/")[2]
   666  			if fs, ok := zonesFilter[zoneId]; ok {
   667  				f := fmt.Sprintf(`(selfLink="%s")`, ig)
   668  				if !utils.IsInStringArray(f, fs) {
   669  					zonesFilter[zoneId] = append(fs, f)
   670  				}
   671  			} else {
   672  				zonesFilter[zoneId] = []string{fmt.Sprintf(`(selfLink="%s")`, ig)}
   673  			}
   674  		}
   675  	}
   676  
   677  	igs := make([]SInstanceGroup, 0)
   678  	// regional instance groups
   679  	if len(regionFilters) > 0 {
   680  		_igs, err := self.region.GetRegionalInstanceGroups(strings.Join(regionFilters, " OR "))
   681  		if err != nil {
   682  			return nil, errors.Wrap(err, "GetRegionalInstanceGroups")
   683  		}
   684  
   685  		igs = append(igs, _igs...)
   686  	}
   687  
   688  	for z, fs := range zonesFilter {
   689  		_igs := make([]SInstanceGroup, 0)
   690  		err := self.region.getInstanceGroups(z, "instanceGroups", strings.Join(fs, " OR "), &_igs)
   691  		if err != nil {
   692  			return nil, errors.Wrap(err, "getInstanceGroups")
   693  		}
   694  
   695  		igs = append(igs, _igs...)
   696  	}
   697  
   698  	self.instanceGroups = igs
   699  	return igs, nil
   700  }
   701  
   702  func (self *SLoadbalancer) GetHealthChecks() ([]HealthChecks, error) {
   703  	if self.healthChecks != nil {
   704  		return self.healthChecks, nil
   705  	}
   706  
   707  	hcs, err := self.region.GetRegionalHealthChecks("")
   708  	if err != nil {
   709  		return nil, errors.Wrap(err, "GetRegionalHealthChecks")
   710  	}
   711  
   712  	ghcs, err := self.region.GetGlobalHealthChecks("")
   713  	if err != nil {
   714  		return nil, errors.Wrap(err, "GetGlobalHealthChecks")
   715  	}
   716  
   717  	self.healthChecks = append(self.healthChecks, ghcs...)
   718  	self.healthChecks = append(self.healthChecks, hcs...)
   719  	return self.healthChecks, err
   720  }
   721  
   722  func (self *SLoadbalancer) GetHealthCheckMaps() (map[string]HealthChecks, error) {
   723  	hcs, err := self.GetHealthChecks()
   724  	if err != nil {
   725  		return nil, errors.Wrap(err, "GetHealthChecks")
   726  	}
   727  
   728  	ret := map[string]HealthChecks{}
   729  	for i := range hcs {
   730  		ret[hcs[i].SelfLink] = hcs[i]
   731  	}
   732  	return ret, err
   733  }