globalloadbalancer.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  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. package google
  15. import (
  16. "context"
  17. "fmt"
  18. "strings"
  19. "yunion.io/x/log"
  20. "yunion.io/x/pkg/errors"
  21. "yunion.io/x/pkg/utils"
  22. api "yunion.io/x/cloudmux/pkg/apis/compute"
  23. "yunion.io/x/cloudmux/pkg/cloudprovider"
  24. "yunion.io/x/cloudmux/pkg/multicloud"
  25. )
  26. type SGlobalLoadbalancer struct {
  27. multicloud.SLoadbalancerBase
  28. GoogleTags
  29. SResourceBase
  30. region *SGlobalRegion
  31. urlMap *SUrlMap // http & https LB
  32. backendServices []SBackendServices // tcp & udp LB. 或者 http & https 后端
  33. instanceGroups []SGlobalInstanceGroup
  34. healthChecks []HealthChecks
  35. forwardRules []SForwardingRule // 服务IP地址
  36. isHttpLb bool // 标记是否为http/https lb
  37. }
  38. func (self *SGlobalLoadbalancer) GetStatus() string {
  39. return api.LB_STATUS_ENABLED
  40. }
  41. func (self *SGlobalLoadbalancer) Refresh() error {
  42. return cloudprovider.ErrNotImplemented
  43. }
  44. func (self *SGlobalLoadbalancer) GetNetworkType() string {
  45. return api.LB_NETWORK_TYPE_VPC
  46. }
  47. func (self *SGlobalLoadbalancer) GetVpcId() string {
  48. return ""
  49. }
  50. func (self *SGlobalLoadbalancer) GetZoneId() string {
  51. return ""
  52. }
  53. func (self *SGlobalLoadbalancer) GetZone1Id() string {
  54. return ""
  55. }
  56. func (self *SGlobalLoadbalancer) GetChargeType() string {
  57. return api.LB_CHARGE_TYPE_BY_TRAFFIC
  58. }
  59. func (self *SGlobalLoadbalancer) GetEgressMbps() int {
  60. return 0
  61. }
  62. func (self *SGlobalLoadbalancer) Delete(ctx context.Context) error {
  63. return cloudprovider.ErrNotImplemented
  64. }
  65. func (self *SGlobalLoadbalancer) Start() error {
  66. return cloudprovider.ErrNotSupported
  67. }
  68. func (self *SGlobalLoadbalancer) Stop() error {
  69. return cloudprovider.ErrNotSupported
  70. }
  71. func (self *SGlobalLoadbalancer) GetSysTags() map[string]string {
  72. frs, err := self.GetForwardingRules()
  73. if err != nil {
  74. return nil
  75. }
  76. ips := []string{}
  77. for i := range frs {
  78. if len(frs[i].IPAddress) > 0 && !utils.IsInStringArray(frs[i].IPAddress, ips) {
  79. ips = append(ips, frs[i].IPAddress)
  80. }
  81. }
  82. data := map[string]string{}
  83. data["FrontendIPs"] = strings.Join(ips, ",")
  84. return data
  85. }
  86. func (self *SGlobalLoadbalancer) GetProjectId() string {
  87. return ""
  88. }
  89. func (self *SGlobalLoadbalancer) GetIEIPs() ([]cloudprovider.ICloudEIP, error) {
  90. frs, err := self.GetForwardingRules()
  91. if err != nil {
  92. log.Errorf("GetAddress.GetForwardingRules %s", err)
  93. }
  94. ret := []cloudprovider.ICloudEIP{}
  95. for i := range frs {
  96. if strings.ToLower(frs[i].LoadBalancingScheme) == "external" {
  97. eips, err := self.region.GetEips(frs[i].IPAddress)
  98. if err != nil {
  99. log.Errorf("GetEips %s", err)
  100. }
  101. for j := range eips {
  102. eips[j].region = self.region
  103. ret = append(ret, &eips[j])
  104. }
  105. }
  106. }
  107. return ret, nil
  108. }
  109. func (self *SGlobalLoadbalancer) GetAddress() string {
  110. var ret []SForwardingRule
  111. if err := self.region.getGlobalLoadbalancerComponents("forwardingRules", "", &ret); err != nil {
  112. return ""
  113. }
  114. for _, item := range ret {
  115. targetResponse, err := _jsonRequest(self.region.client.client, "GET", item.Target, nil, false)
  116. if err != nil {
  117. return ""
  118. }
  119. var target interface{}
  120. switch {
  121. case strings.Contains(item.Target, "targetHttpProxies"):
  122. target = new(STargetHttpProxy)
  123. case strings.Contains(item.Target, "targetHttpsProxies"):
  124. target = new(STargetHttpsProxy)
  125. case strings.Contains(item.Target, "targetTcpProxies"):
  126. target = new(STargetTcpProxy)
  127. default:
  128. continue
  129. }
  130. if err := targetResponse.Unmarshal(target); err != nil {
  131. return ""
  132. }
  133. match, err := self.isNameMatch(target)
  134. if err != nil {
  135. log.Errorf("isNameMatch error: %v", err)
  136. continue
  137. }
  138. if match {
  139. return item.IPAddress
  140. }
  141. }
  142. return ""
  143. }
  144. func (self *SGlobalLoadbalancer) GetAddressType() string {
  145. frs, err := self.GetForwardingRules()
  146. if err != nil {
  147. return api.LB_ADDR_TYPE_INTRANET
  148. }
  149. for i := range frs {
  150. sche := strings.ToLower(frs[i].LoadBalancingScheme)
  151. if !utils.IsInStringArray(sche, []string{"invalid", "undefinedloadbalancingscheme"}) {
  152. if sche == "external" {
  153. return api.LB_ADDR_TYPE_INTERNET
  154. } else {
  155. return api.LB_ADDR_TYPE_INTRANET
  156. }
  157. }
  158. }
  159. return api.LB_ADDR_TYPE_INTERNET
  160. }
  161. func (self *SGlobalLoadbalancer) GetNetworkIds() []string {
  162. igs, err := self.GetInstanceGroups()
  163. if err != nil {
  164. log.Errorf("GetInstanceGroups %s", err)
  165. return nil
  166. }
  167. selfLinks := make([]string, 0)
  168. networkIds := make([]string, 0)
  169. for i := range igs {
  170. if utils.IsInStringArray(igs[i].Subnetwork, selfLinks) {
  171. selfLinks = append(selfLinks, igs[i].Subnetwork)
  172. network := SResourceBase{
  173. Name: "",
  174. SelfLink: igs[i].Network,
  175. }
  176. networkIds = append(networkIds, network.GetGlobalId())
  177. }
  178. }
  179. return networkIds
  180. }
  181. func (self *SGlobalLoadbalancer) GetLoadbalancerSpec() string {
  182. if self.isHttpLb {
  183. return "global_http_lb"
  184. }
  185. return fmt.Sprintf("global_%s", strings.ToLower(self.backendServices[0].Protocol))
  186. }
  187. func (self *SGlobalLoadbalancer) GetILoadBalancerListeners() ([]cloudprovider.ICloudLoadbalancerListener, error) {
  188. lbls, err := self.GetLoadbalancerListeners()
  189. if err != nil {
  190. return nil, errors.Wrap(err, "GetLoadbalancerListeners")
  191. }
  192. ilbls := make([]cloudprovider.ICloudLoadbalancerListener, len(lbls))
  193. for i := range lbls {
  194. ilbls[i] = &lbls[i]
  195. }
  196. return ilbls, nil
  197. }
  198. func (self *SGlobalLoadbalancer) GetILoadBalancerBackendGroups() ([]cloudprovider.ICloudLoadbalancerBackendGroup, error) {
  199. lbbgs, err := self.GetLoadbalancerBackendGroups()
  200. if err != nil {
  201. return nil, errors.Wrap(err, "GetLoadbalancerBackendGroups")
  202. }
  203. ilbbgs := make([]cloudprovider.ICloudLoadbalancerBackendGroup, len(lbbgs))
  204. for i := range lbbgs {
  205. ilbbgs[i] = &lbbgs[i]
  206. }
  207. return ilbbgs, nil
  208. }
  209. func (self *SGlobalLoadbalancer) CreateILoadBalancerBackendGroup(group *cloudprovider.SLoadbalancerBackendGroup) (cloudprovider.ICloudLoadbalancerBackendGroup, error) {
  210. return nil, cloudprovider.ErrNotSupported
  211. }
  212. func (self *SGlobalLoadbalancer) GetILoadBalancerBackendGroupById(groupId string) (cloudprovider.ICloudLoadbalancerBackendGroup, error) {
  213. lbbgs, err := self.GetLoadbalancerBackendGroups()
  214. if err != nil {
  215. return nil, errors.Wrap(err, "GetLoadbalancerBackendGroups")
  216. }
  217. for i := range lbbgs {
  218. if lbbgs[i].GetGlobalId() == groupId {
  219. return &lbbgs[i], nil
  220. }
  221. }
  222. return nil, cloudprovider.ErrNotFound
  223. }
  224. func (self *SGlobalLoadbalancer) CreateILoadBalancerListener(ctx context.Context, listener *cloudprovider.SLoadbalancerListenerCreateOptions) (cloudprovider.ICloudLoadbalancerListener, error) {
  225. return nil, cloudprovider.ErrNotSupported
  226. }
  227. func (self *SGlobalLoadbalancer) GetILoadBalancerListenerById(listenerId string) (cloudprovider.ICloudLoadbalancerListener, error) {
  228. lbls, err := self.GetLoadbalancerListeners()
  229. if err != nil {
  230. return nil, errors.Wrap(err, "GetLoadbalancerBackendGroups")
  231. }
  232. for i := range lbls {
  233. if lbls[i].GetGlobalId() == listenerId {
  234. return &lbls[i], nil
  235. }
  236. }
  237. return nil, cloudprovider.ErrNotFound
  238. }
  239. func (self *SGlobalRegion) getGlobalLoadbalancerComponents(resource string, filter string, result interface{}) error {
  240. url := fmt.Sprintf("global/%s", resource)
  241. params := map[string]string{}
  242. if len(filter) > 0 {
  243. params["filter"] = filter
  244. }
  245. err := self.ListAll(url, params, result)
  246. if err != nil {
  247. return errors.Wrap(err, "ListAll")
  248. }
  249. return nil
  250. }
  251. func (self *SGlobalRegion) GetGlobalHTTPLoadbalancers() ([]SGlobalLoadbalancer, error) {
  252. ums, err := self.GetGlobalUrlMaps("")
  253. if err != nil {
  254. return nil, errors.Wrap(err, "GetGlobalUrlMaps")
  255. }
  256. lbs := make([]SGlobalLoadbalancer, len(ums))
  257. for i := range ums {
  258. lbs[i] = SGlobalLoadbalancer{
  259. region: self,
  260. SResourceBase: SResourceBase{
  261. Name: ums[i].Name,
  262. SelfLink: ums[i].SelfLink,
  263. },
  264. urlMap: &ums[i],
  265. backendServices: nil,
  266. forwardRules: nil,
  267. isHttpLb: true,
  268. }
  269. }
  270. return lbs, nil
  271. }
  272. func (self *SGlobalRegion) GetGlobalTcpLoadbalancers() ([]SGlobalLoadbalancer, error) {
  273. bss, err := self.GetGlobalBackendServices("protocol eq TCP")
  274. if err != nil {
  275. return nil, errors.Wrap(err, "GetGlobalBackendServices")
  276. }
  277. lbs := make([]SGlobalLoadbalancer, len(bss))
  278. for i := range bss {
  279. lbs[i] = SGlobalLoadbalancer{
  280. region: self,
  281. SResourceBase: SResourceBase{
  282. Name: bss[i].Name,
  283. SelfLink: bss[i].SelfLink,
  284. },
  285. urlMap: nil,
  286. backendServices: []SBackendServices{bss[i]},
  287. forwardRules: nil,
  288. }
  289. }
  290. return lbs, nil
  291. }
  292. func (self *SGlobalRegion) GetGlobalUdpLoadbalancers() ([]SGlobalLoadbalancer, error) {
  293. bss, err := self.GetGlobalBackendServices("protocol eq UDP")
  294. if err != nil {
  295. return nil, errors.Wrap(err, "GetGlobalBackendServices")
  296. }
  297. lbs := make([]SGlobalLoadbalancer, len(bss))
  298. for i := range bss {
  299. lbs[i] = SGlobalLoadbalancer{
  300. region: self,
  301. SResourceBase: SResourceBase{
  302. Name: bss[i].Name,
  303. SelfLink: bss[i].SelfLink,
  304. },
  305. urlMap: nil,
  306. backendServices: []SBackendServices{bss[i]},
  307. forwardRules: nil,
  308. }
  309. }
  310. return lbs, nil
  311. }
  312. func (self *SGlobalRegion) GetGlobalLoadbalancers() ([]SGlobalLoadbalancer, error) {
  313. lbs := make([]SGlobalLoadbalancer, 0)
  314. funcs := []func() ([]SGlobalLoadbalancer, error){self.GetGlobalHTTPLoadbalancers, self.GetGlobalTcpLoadbalancers, self.GetGlobalUdpLoadbalancers}
  315. for i := range funcs {
  316. _lbs, err := funcs[i]()
  317. if err != nil {
  318. return nil, errors.Wrap(err, "GetGlobalLoadbalancers")
  319. }
  320. lbs = append(lbs, _lbs...)
  321. }
  322. return lbs, nil
  323. }
  324. func (self *SGlobalRegion) GetLoadbalancer(resourceId string) (SGlobalLoadbalancer, error) {
  325. lb := SGlobalLoadbalancer{}
  326. var err error
  327. if strings.Contains(resourceId, "/urlMaps/") {
  328. ret := SUrlMap{}
  329. err = self.GetBySelfId(resourceId, &ret)
  330. lb.isHttpLb = true
  331. lb.urlMap = &ret
  332. lb.SResourceBase = SResourceBase{
  333. Name: ret.Name,
  334. SelfLink: ret.SelfLink,
  335. }
  336. } else {
  337. ret := SBackendServices{}
  338. err = self.GetBySelfId(resourceId, &ret)
  339. lb.backendServices = []SBackendServices{ret}
  340. lb.SResourceBase = SResourceBase{
  341. Name: ret.Name,
  342. SelfLink: ret.SelfLink,
  343. }
  344. }
  345. if err != nil {
  346. return lb, errors.Wrapf(err, "get")
  347. }
  348. lb.region = self
  349. return lb, nil
  350. }
  351. func (self *SGlobalRegion) GetILoadBalancerById(loadbalancerId string) (cloudprovider.ICloudLoadbalancer, error) {
  352. lb, err := self.GetLoadbalancer(loadbalancerId)
  353. if err != nil {
  354. return nil, errors.Wrap(err, "GetLoadbalancer")
  355. }
  356. return &lb, nil
  357. }