albrule.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  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 aliyun
  15. import (
  16. "context"
  17. "yunion.io/x/jsonutils"
  18. api "yunion.io/x/cloudmux/pkg/apis/compute"
  19. "yunion.io/x/cloudmux/pkg/cloudprovider"
  20. "yunion.io/x/cloudmux/pkg/multicloud"
  21. )
  22. type SAlbRule struct {
  23. multicloud.SResourceBase
  24. multicloud.SLoadbalancerRedirectBase
  25. AliyunTags
  26. albListener *SAlbListener
  27. RuleId string `json:"RuleId"`
  28. RuleName string `json:"RuleName"`
  29. RuleStatus string `json:"RuleStatus"`
  30. Priority int `json:"Priority"`
  31. ListenerId string `json:"ListenerId"`
  32. LoadBalancerId string `json:"LoadBalancerId"`
  33. RuleConditions []RuleCondition `json:"RuleConditions"`
  34. RuleActions []AlbRuleAction `json:"RuleActions"`
  35. Direction string `json:"Direction"`
  36. CreateTime string `json:"CreateTime"`
  37. RegionId string `json:"RegionId"`
  38. }
  39. type RuleCondition struct {
  40. Type string `json:"Type"`
  41. HostConfig HostConfig `json:"HostConfig"`
  42. PathConfig PathConfig `json:"PathConfig"`
  43. MethodConfig MethodConfig `json:"MethodConfig"`
  44. QueryStringConfig QueryStringConfig `json:"QueryStringConfig"`
  45. HeaderConfig HeaderConfig `json:"HeaderConfig"`
  46. CookieConfig CookieConfig `json:"CookieConfig"`
  47. SourceIpConfig SourceIpConfig `json:"SourceIpConfig"`
  48. ResponseHeaderConfig ResponseHeaderConfig `json:"ResponseHeaderConfig"`
  49. ResponseStatusCodeConfig ResponseStatusCodeConfig `json:"ResponseStatusCodeConfig"`
  50. }
  51. type AlbRuleAction struct {
  52. Type string `json:"Type"`
  53. Order int `json:"Order"`
  54. ForwardGroupConfig ForwardGroupConfig `json:"ForwardGroupConfig"`
  55. }
  56. type HostConfig struct {
  57. Values []string `json:"Values"`
  58. }
  59. type PathConfig struct {
  60. Values []string `json:"Values"`
  61. }
  62. type MethodConfig struct {
  63. Values []string `json:"Values"`
  64. }
  65. type QueryStringConfig struct {
  66. Values []QueryStringValue `json:"Values"`
  67. }
  68. type QueryStringValue struct {
  69. Key string `json:"Key"`
  70. Value string `json:"Value"`
  71. }
  72. type HeaderConfig struct {
  73. Key string `json:"Key"`
  74. Values []string `json:"Values"`
  75. }
  76. type CookieConfig struct {
  77. Values []CookieValue `json:"Values"`
  78. }
  79. type CookieValue struct {
  80. Key string `json:"Key"`
  81. Value string `json:"Value"`
  82. }
  83. type SourceIpConfig struct {
  84. Values []string `json:"Values"`
  85. }
  86. type ResponseHeaderConfig struct {
  87. Key string `json:"Key"`
  88. Values []string `json:"Values"`
  89. }
  90. type ResponseStatusCodeConfig struct {
  91. Values []string `json:"Values"`
  92. }
  93. func (rule *SAlbRule) GetName() string {
  94. return rule.RuleName
  95. }
  96. func (rule *SAlbRule) GetId() string {
  97. return rule.RuleId
  98. }
  99. func (rule *SAlbRule) GetGlobalId() string {
  100. return rule.RuleId
  101. }
  102. func (rule *SAlbRule) GetStatus() string {
  103. switch rule.RuleStatus {
  104. case "Available":
  105. return api.LB_STATUS_ENABLED
  106. case "Configuring":
  107. return api.LB_STATUS_UNKNOWN
  108. default:
  109. return api.LB_STATUS_UNKNOWN
  110. }
  111. }
  112. func (rule *SAlbRule) IsDefault() bool {
  113. return false
  114. }
  115. func (rule *SAlbRule) IsEmulated() bool {
  116. return false
  117. }
  118. func (rule *SAlbRule) Refresh() error {
  119. r, err := rule.albListener.alb.region.GetAlbRule(rule.RuleId)
  120. if err != nil {
  121. return err
  122. }
  123. return jsonutils.Update(rule, r)
  124. }
  125. func (rule *SAlbRule) GetCondition() string {
  126. return ""
  127. }
  128. func (rule *SAlbRule) GetDomain() string {
  129. for _, condition := range rule.RuleConditions {
  130. if condition.Type == "Host" && len(condition.HostConfig.Values) > 0 {
  131. return condition.HostConfig.Values[0]
  132. }
  133. }
  134. return ""
  135. }
  136. func (rule *SAlbRule) GetPath() string {
  137. for _, condition := range rule.RuleConditions {
  138. if condition.Type == "Path" && len(condition.PathConfig.Values) > 0 {
  139. return condition.PathConfig.Values[0]
  140. }
  141. }
  142. return ""
  143. }
  144. func (rule *SAlbRule) GetProjectId() string {
  145. return rule.albListener.GetProjectId()
  146. }
  147. func (rule *SAlbRule) GetBackendGroupId() string {
  148. for _, action := range rule.RuleActions {
  149. if action.Type == "ForwardGroup" && len(action.ForwardGroupConfig.ServerGroupTuples) > 0 {
  150. return action.ForwardGroupConfig.ServerGroupTuples[0].ServerGroupId
  151. }
  152. }
  153. return ""
  154. }
  155. func (rule *SAlbRule) GetBackendGroups() ([]string, error) {
  156. return nil, cloudprovider.ErrNotImplemented
  157. }
  158. func (rule *SAlbRule) GetRedirectPool() (cloudprovider.SRedirectPool, error) {
  159. return cloudprovider.SRedirectPool{}, cloudprovider.ErrNotImplemented
  160. }
  161. func (rule *SAlbRule) Delete(ctx context.Context) error {
  162. return rule.albListener.alb.region.DeleteAlbRule(rule.RuleId)
  163. }
  164. func (rule *SAlbRule) Update(ctx context.Context, opts *cloudprovider.SLoadbalancerListenerRule) error {
  165. return cloudprovider.ErrNotImplemented
  166. }
  167. // region methods
  168. func (region *SRegion) GetAlbRules(listenerId string) ([]SAlbRule, error) {
  169. params := map[string]string{
  170. "RegionId": region.RegionId,
  171. "ListenerIds.1": listenerId,
  172. }
  173. body, err := region.albRequest("ListRules", params)
  174. if err != nil {
  175. return nil, err
  176. }
  177. rules := []SAlbRule{}
  178. err = body.Unmarshal(&rules, "Rules")
  179. if err != nil {
  180. return nil, err
  181. }
  182. return rules, nil
  183. }
  184. func (region *SRegion) GetAlbRule(ruleId string) (*SAlbRule, error) {
  185. rules, err := region.GetAlbRules("")
  186. if err != nil {
  187. return nil, err
  188. }
  189. for _, rule := range rules {
  190. if rule.RuleId == ruleId {
  191. return &rule, nil
  192. }
  193. }
  194. return nil, cloudprovider.ErrNotFound
  195. }
  196. func (region *SRegion) CreateAlbRule(listenerId string, rule *cloudprovider.SLoadbalancerListenerRule) (*SAlbRule, error) {
  197. params := map[string]string{
  198. "RegionId": region.RegionId,
  199. "ListenerId": listenerId,
  200. "RuleName": rule.Name,
  201. "Priority": "100",
  202. }
  203. // 构建规则条件
  204. conditions := jsonutils.NewArray()
  205. if len(rule.Domain) > 0 {
  206. condition := jsonutils.Marshal(map[string]interface{}{
  207. "Type": "Host",
  208. "HostConfig": map[string]interface{}{
  209. "Values": []string{rule.Domain},
  210. },
  211. })
  212. conditions.Add(condition)
  213. }
  214. if len(rule.Path) > 0 {
  215. condition := jsonutils.Marshal(map[string]interface{}{
  216. "Type": "Path",
  217. "PathConfig": map[string]interface{}{
  218. "Values": []string{rule.Path},
  219. },
  220. })
  221. conditions.Add(condition)
  222. }
  223. params["RuleConditions"] = conditions.String()
  224. // 构建规则动作
  225. actions := jsonutils.NewArray()
  226. if len(rule.BackendGroupId) > 0 {
  227. action := jsonutils.Marshal(map[string]interface{}{
  228. "Type": "ForwardGroup",
  229. "Order": 1,
  230. "ForwardGroupConfig": map[string]interface{}{
  231. "ServerGroupTuples": []map[string]interface{}{
  232. {
  233. "ServerGroupId": rule.BackendGroupId,
  234. "Weight": 100,
  235. },
  236. },
  237. },
  238. })
  239. actions.Add(action)
  240. }
  241. params["RuleActions"] = actions.String()
  242. body, err := region.albRequest("CreateRule", params)
  243. if err != nil {
  244. return nil, err
  245. }
  246. ruleId, err := body.GetString("RuleId")
  247. if err != nil {
  248. return nil, err
  249. }
  250. return region.GetAlbRule(ruleId)
  251. }
  252. func (region *SRegion) DeleteAlbRule(ruleId string) error {
  253. params := map[string]string{
  254. "RegionId": region.RegionId,
  255. "RuleId": ruleId,
  256. }
  257. _, err := region.albRequest("DeleteRule", params)
  258. return err
  259. }