loadbalancer.go 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  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 azure
  15. import (
  16. "context"
  17. "fmt"
  18. "net/url"
  19. "strings"
  20. "yunion.io/x/jsonutils"
  21. "yunion.io/x/pkg/errors"
  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 SLoadbalancer struct {
  27. multicloud.SLoadbalancerBase
  28. AzureTags
  29. region *SRegion
  30. Name string `json:"name"`
  31. ID string `json:"id"`
  32. Etag string `json:"etag"`
  33. Type string `json:"type"`
  34. Location string `json:"location"`
  35. Properties *SLoadbalancerProperties `json:"properties"`
  36. Sku Sku `json:"sku"`
  37. }
  38. func (self *SLoadbalancer) GetId() string {
  39. return self.ID
  40. }
  41. func (self *SLoadbalancer) GetName() string {
  42. return self.Name
  43. }
  44. func (self *SLoadbalancer) GetGlobalId() string {
  45. return strings.ToLower(self.GetId())
  46. }
  47. func (self *SLoadbalancer) GetProperties() (*SLoadbalancerProperties, error) {
  48. if self.Properties != nil {
  49. return self.Properties, nil
  50. }
  51. lb, err := self.region.GetLoadbalancer(self.ID)
  52. if err != nil {
  53. return nil, err
  54. }
  55. self.Properties = lb.Properties
  56. return self.Properties, nil
  57. }
  58. func (self *SLoadbalancer) GetStatus() string {
  59. properties, err := self.GetProperties()
  60. if err != nil {
  61. return api.LB_STATUS_UNKNOWN
  62. }
  63. switch properties.ProvisioningState {
  64. case "Deleting":
  65. return api.LB_STATUS_DELETING
  66. case "Failed":
  67. return api.LB_STATUS_START_FAILED
  68. case "Updating":
  69. return api.LB_SYNC_CONF
  70. }
  71. switch self.Properties.OperationalState {
  72. case "Running":
  73. return api.LB_STATUS_ENABLED
  74. case "Stopped":
  75. return api.LB_STATUS_DISABLED
  76. case "Starting", "Stopping":
  77. return api.LB_SYNC_CONF
  78. default:
  79. if self.Properties.ProvisioningState == "Succeeded" {
  80. return api.LB_STATUS_ENABLED
  81. }
  82. return api.LB_STATUS_UNKNOWN
  83. }
  84. }
  85. func (self *SLoadbalancer) Refresh() error {
  86. lb, err := self.region.GetLoadbalancer(self.ID)
  87. if err != nil {
  88. return errors.Wrap(err, "GetLoadbalancer")
  89. }
  90. return jsonutils.Update(self, lb)
  91. }
  92. func (self *SLoadbalancer) GetProjectId() string {
  93. return getResourceGroup(self.ID)
  94. }
  95. func (self *SLoadbalancer) GetAddress() string {
  96. properties, err := self.GetProperties()
  97. if err != nil {
  98. return ""
  99. }
  100. for _, front := range properties.FrontendIPConfigurations {
  101. if len(front.Properties.PrivateIPAddress) > 0 {
  102. return front.Properties.PrivateIPAddress
  103. }
  104. }
  105. return ""
  106. }
  107. func (self *SLoadbalancer) GetAddressType() string {
  108. netIds := self.GetNetworkIds()
  109. if len(netIds) > 0 {
  110. return api.LB_ADDR_TYPE_INTRANET
  111. }
  112. return api.LB_ADDR_TYPE_INTERNET
  113. }
  114. func (self *SLoadbalancer) GetNetworkType() string {
  115. return api.LB_NETWORK_TYPE_VPC
  116. }
  117. func (self *SLoadbalancer) GetNetworkIds() []string {
  118. properties, err := self.GetProperties()
  119. if err != nil {
  120. return []string{}
  121. }
  122. for _, front := range properties.FrontendIPConfigurations {
  123. if len(front.Properties.Subnet.ID) > 0 {
  124. return []string{strings.ToLower(front.Properties.Subnet.ID)}
  125. }
  126. }
  127. for _, gateway := range properties.GatewayIPConfigurations {
  128. if len(gateway.Properties.Subnet.ID) > 0 {
  129. return []string{strings.ToLower(gateway.Properties.Subnet.ID)}
  130. }
  131. }
  132. return []string{}
  133. }
  134. func (self *SLoadbalancer) GetVpcId() string {
  135. ids := self.GetNetworkIds()
  136. for _, netId := range ids {
  137. if strings.Contains(netId, "/subnets") {
  138. return strings.Split(netId, "/subnets")[0]
  139. }
  140. }
  141. return ""
  142. }
  143. func (self *SLoadbalancer) GetZoneId() string {
  144. return ""
  145. }
  146. func (self *SLoadbalancer) GetZone1Id() string {
  147. return ""
  148. }
  149. func (self *SLoadbalancer) GetLoadbalancerSpec() string {
  150. if len(self.Sku.Name) > 0 {
  151. return self.Sku.Name
  152. }
  153. properties, err := self.GetProperties()
  154. if err != nil {
  155. return ""
  156. }
  157. return properties.Sku.Name
  158. }
  159. func (self *SLoadbalancer) GetChargeType() string {
  160. return api.LB_CHARGE_TYPE_BY_TRAFFIC
  161. }
  162. func (self *SLoadbalancer) GetEgressMbps() int {
  163. return 0
  164. }
  165. func (self *SLoadbalancer) GetIEIPs() ([]cloudprovider.ICloudEIP, error) {
  166. properties, err := self.GetProperties()
  167. if err != nil {
  168. return nil, errors.Wrapf(err, "GetProperties")
  169. }
  170. ret := []cloudprovider.ICloudEIP{}
  171. for _, front := range properties.FrontendIPConfigurations {
  172. if len(front.Properties.PublicIPAddress.ID) > 0 {
  173. eip, err := self.region.GetEip(front.Properties.PublicIPAddress.ID)
  174. if err != nil {
  175. return nil, err
  176. }
  177. ret = append(ret, eip)
  178. }
  179. }
  180. return ret, nil
  181. }
  182. func (self *SLoadbalancer) Delete(ctx context.Context) error {
  183. return errors.Wrap(cloudprovider.ErrNotImplemented, "Delete")
  184. }
  185. func (self *SLoadbalancer) Start() error {
  186. return errors.Wrap(cloudprovider.ErrNotImplemented, "Start")
  187. }
  188. func (self *SLoadbalancer) Stop() error {
  189. return errors.Wrap(cloudprovider.ErrNotImplemented, "Stop")
  190. }
  191. func (self *SLoadbalancer) GetILoadBalancerListeners() ([]cloudprovider.ICloudLoadbalancerListener, error) {
  192. properties, err := self.GetProperties()
  193. if err != nil {
  194. return nil, err
  195. }
  196. ret := []cloudprovider.ICloudLoadbalancerListener{}
  197. idMap := map[string]bool{}
  198. for _, listeners := range [][]SLoadBalancerListener{
  199. properties.InboundNatRules,
  200. properties.OutboundRules,
  201. properties.LoadBalancingRules,
  202. } {
  203. for i := range listeners {
  204. listener := listeners[i]
  205. listener.lb = self
  206. if _, ok := idMap[listener.GetGlobalId()]; !ok {
  207. ret = append(ret, &listener)
  208. idMap[listener.GetGlobalId()] = true
  209. }
  210. }
  211. }
  212. for i := range properties.HTTPListeners {
  213. listener := properties.HTTPListeners[i]
  214. listener.lb = self
  215. if _, ok := idMap[listener.GetGlobalId()]; !ok {
  216. ret = append(ret, &listener)
  217. idMap[listener.GetGlobalId()] = true
  218. }
  219. }
  220. return ret, nil
  221. }
  222. func (self *SLoadbalancer) CreateILoadBalancerBackendGroup(group *cloudprovider.SLoadbalancerBackendGroup) (cloudprovider.ICloudLoadbalancerBackendGroup, error) {
  223. return nil, errors.Wrap(cloudprovider.ErrNotImplemented, "CreateILoadBalancerBackendGroup")
  224. }
  225. func (self *SLoadbalancer) CreateILoadBalancerListener(ctx context.Context, listener *cloudprovider.SLoadbalancerListenerCreateOptions) (cloudprovider.ICloudLoadbalancerListener, error) {
  226. return nil, errors.Wrap(cloudprovider.ErrNotImplemented, "CreateILoadBalancerListener")
  227. }
  228. func (self *SLoadbalancer) GetILoadBalancerListenerById(id string) (cloudprovider.ICloudLoadbalancerListener, error) {
  229. lblis, err := self.GetILoadBalancerListeners()
  230. if err != nil {
  231. return nil, err
  232. }
  233. for i := range lblis {
  234. if lblis[i].GetGlobalId() == id {
  235. return lblis[i], nil
  236. }
  237. }
  238. return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%s", id)
  239. }
  240. func (self *SLoadbalancer) GetILoadBalancerCertificates() ([]cloudprovider.ICloudLoadbalancerCertificate, error) {
  241. return nil, cloudprovider.ErrNotImplemented
  242. }
  243. func (self *SLoadbalancer) GetILoadBalancerCertificateById(certId string) (cloudprovider.ICloudLoadbalancerCertificate, error) {
  244. return nil, cloudprovider.ErrNotImplemented
  245. }
  246. func (self *SLoadbalancer) GetILoadBalancerBackendGroups() ([]cloudprovider.ICloudLoadbalancerBackendGroup, error) {
  247. ret := []cloudprovider.ICloudLoadbalancerBackendGroup{}
  248. properties, err := self.GetProperties()
  249. if err != nil {
  250. return nil, err
  251. }
  252. idMap := map[string]bool{}
  253. for _, rule := range properties.InboundNatRules {
  254. if len(rule.Properties.BackendIPConfiguration.Id) == 0 {
  255. continue
  256. }
  257. lbbg := &SLoadbalancerBackendGroup{lb: self, Id: rule.Properties.BackendIPConfiguration.Id}
  258. if _, ok := idMap[lbbg.GetGlobalId()]; !ok {
  259. ret = append(ret, lbbg)
  260. idMap[lbbg.GetGlobalId()] = true
  261. }
  262. }
  263. for _, pool := range properties.BackendAddressPools {
  264. lbbg := &SLoadbalancerBackendGroup{lb: self, Id: pool.Id, BackendIPConfigurations: pool.Properties.BackendIPConfigurations}
  265. if _, ok := idMap[lbbg.GetGlobalId()]; !ok {
  266. ret = append(ret, lbbg)
  267. idMap[lbbg.GetGlobalId()] = true
  268. }
  269. }
  270. return ret, nil
  271. }
  272. func (self *SLoadbalancer) GetILoadBalancerBackendGroupById(groupId string) (cloudprovider.ICloudLoadbalancerBackendGroup, error) {
  273. lbbgs, err := self.GetILoadBalancerBackendGroups()
  274. if err != nil {
  275. return nil, err
  276. }
  277. for i := range lbbgs {
  278. if lbbgs[i].GetGlobalId() == groupId {
  279. return lbbgs[i], nil
  280. }
  281. }
  282. return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%s", groupId)
  283. }
  284. func (self *SRegion) GetLoadbalancers() ([]SLoadbalancer, error) {
  285. params := url.Values{}
  286. params.Add("$filter", fmt.Sprintf("location eq '%s'", self.Name))
  287. params.Add("$filter", "(resourceType eq 'Microsoft.Network/applicationGateways' or resourceType eq 'Microsoft.Network/loadBalancers')")
  288. resp, err := self.client.list_v2("resources", "2024-03-01", params)
  289. if err != nil {
  290. return nil, err
  291. }
  292. ret := []SLoadbalancer{}
  293. err = resp.Unmarshal(&ret, "value")
  294. if err != nil {
  295. return nil, err
  296. }
  297. return ret, nil
  298. }
  299. func (self *SRegion) GetLoadbalancer(id string) (*SLoadbalancer, error) {
  300. resp, err := self.show(id, "2023-11-01")
  301. if err != nil {
  302. return nil, err
  303. }
  304. ret := &SLoadbalancer{region: self}
  305. err = resp.Unmarshal(ret)
  306. if err != nil {
  307. return nil, err
  308. }
  309. return ret, nil
  310. }