securityruleset.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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 secrules
  15. import (
  16. "bytes"
  17. "fmt"
  18. "sort"
  19. )
  20. type SecurityGroupSubSubRuleSet struct {
  21. ipKey string
  22. rules []SecurityRule
  23. }
  24. func (sssrs *SecurityGroupSubSubRuleSet) addRule(rule SecurityRule) {
  25. if sssrs.rules == nil {
  26. sssrs.ipKey = rule.getIPKey()
  27. sssrs.rules = []SecurityRule{rule}
  28. return
  29. }
  30. if sssrs.ipKey != rule.getIPKey() {
  31. panic(fmt.Sprintf("rule ip key %s not equal %s", sssrs.ipKey, rule.getIPKey()))
  32. }
  33. idx := 0
  34. for idx < len(sssrs.rules) {
  35. rel := sssrs.rules[idx].protoRelation(rule)
  36. switch rel {
  37. case RELATION_INDEPENDENT:
  38. idx++
  39. case RELATION_IDENTICAL, RELATION_SUPERSET:
  40. return
  41. case RELATION_SUBSET:
  42. sssrs.rules = append(sssrs.rules[:idx], sssrs.rules[idx+1:]...)
  43. case RELATION_NEXT_AHEAD, RELATION_NEXT_AFTER, RELATION_OVERLAP:
  44. rule = rule.merge(sssrs.rules[idx])
  45. sssrs.rules = append(sssrs.rules[:idx], sssrs.rules[idx+1:]...)
  46. idx = 0
  47. }
  48. }
  49. sssrs.rules = append(sssrs.rules, rule)
  50. }
  51. type SecurityGroupSubRuleSet struct {
  52. allowRules *SecurityGroupSubSubRuleSet
  53. denyRules *SecurityGroupSubSubRuleSet
  54. }
  55. func (ssrs *SecurityGroupSubRuleSet) addRule(rule SecurityRule) {
  56. if rule.Action == SecurityRuleAllow {
  57. if ssrs.allowRules == nil {
  58. ssrs.allowRules = &SecurityGroupSubSubRuleSet{}
  59. }
  60. ssrs.allowRules.addRule(rule)
  61. } else {
  62. if ssrs.denyRules == nil {
  63. ssrs.denyRules = &SecurityGroupSubSubRuleSet{}
  64. }
  65. ssrs.denyRules.addRule(rule)
  66. }
  67. }
  68. func (ssrs *SecurityGroupSubRuleSet) getDirectionRules() ([]SecurityRule, []SecurityRule) {
  69. inRules, outRules := []SecurityRule{}, []SecurityRule{}
  70. if ssrs.allowRules != nil {
  71. for _, rule := range ssrs.allowRules.rules {
  72. if rule.Direction == DIR_IN {
  73. inRules = append(inRules, rule)
  74. } else {
  75. outRules = append(outRules, rule)
  76. }
  77. }
  78. }
  79. return inRules, outRules
  80. }
  81. func isRuleEqual(rules []SecurityRule, _rules []SecurityRule) bool {
  82. if len(rules) != len(_rules) {
  83. return false
  84. }
  85. sort.SliceStable(rules, func(i, j int) bool {
  86. if rules[i].Priority < rules[j].Priority {
  87. return true
  88. } else if rules[i].Priority == rules[j].Priority {
  89. return rules[i].String() < rules[j].String()
  90. }
  91. return false
  92. })
  93. sort.SliceStable(_rules, func(i, j int) bool {
  94. if _rules[i].Priority < _rules[j].Priority {
  95. return true
  96. } else if _rules[i].Priority == _rules[j].Priority {
  97. return _rules[i].String() < _rules[j].String()
  98. }
  99. return false
  100. })
  101. for i := 0; i < len(rules); i++ {
  102. if rules[i].String() != _rules[i].String() {
  103. return false
  104. }
  105. }
  106. return true
  107. }
  108. func (ssrs *SecurityGroupSubRuleSet) isEqual(_ssrs *SecurityGroupSubRuleSet) bool {
  109. if _ssrs == nil {
  110. return false
  111. }
  112. inRules, outRules := ssrs.getDirectionRules()
  113. _inRules, _outRules := _ssrs.getDirectionRules()
  114. return isRuleEqual(inRules, _inRules) && isRuleEqual(outRules, _outRules)
  115. }
  116. type SecurityGroupRuleSet struct {
  117. rules map[string]*SecurityGroupSubRuleSet
  118. }
  119. func (srs *SecurityGroupRuleSet) AddRule(rule SecurityRule) {
  120. if srs.rules == nil {
  121. srs.rules = map[string]*SecurityGroupSubRuleSet{}
  122. }
  123. key := rule.getIPKey()
  124. if _, ok := srs.rules[key]; !ok {
  125. srs.rules[key] = &SecurityGroupSubRuleSet{}
  126. }
  127. ssrs := srs.rules[key]
  128. if len(rule.Ports) > 0 {
  129. ports := rule.Ports
  130. //规则合并时,是依据PortStart和PortEnd,因此将多个不连续的端口拆分为单个端口连续的规则进行合并
  131. rule.Ports = []int{}
  132. for i := 0; i < len(ports); i++ {
  133. rule.PortStart = ports[i]
  134. rule.PortEnd = ports[i]
  135. ssrs.addRule(rule)
  136. }
  137. return
  138. }
  139. ssrs.addRule(rule)
  140. }
  141. func (srs *SecurityGroupRuleSet) getSubRuleSet(key string) *SecurityGroupSubRuleSet {
  142. if srs.rules == nil {
  143. return nil
  144. }
  145. s, ok := srs.rules[key]
  146. if !ok {
  147. return nil
  148. }
  149. return s
  150. }
  151. func (srs *SecurityGroupRuleSet) getAllowRules() []SecurityRule {
  152. rules := []SecurityRule{}
  153. for _, v := range srs.rules {
  154. if v.allowRules != nil {
  155. rules = append(rules, v.allowRules.rules...)
  156. }
  157. }
  158. return rules
  159. }
  160. func (srs *SecurityGroupRuleSet) getDenyRules() []SecurityRule {
  161. rules := []SecurityRule{}
  162. for _, v := range srs.rules {
  163. if v.denyRules != nil {
  164. rules = append(rules, v.denyRules.rules...)
  165. }
  166. }
  167. return rules
  168. }
  169. func (srs *SecurityGroupRuleSet) IsEqual(src SecurityGroupRuleSet) bool {
  170. if len(srs.rules) != len(src.rules) {
  171. return false
  172. }
  173. for k, v := range srs.rules {
  174. _v := src.getSubRuleSet(k)
  175. if !v.isEqual(_v) {
  176. return false
  177. }
  178. }
  179. return true
  180. }
  181. func (srs *SecurityGroupRuleSet) String() string {
  182. buf := bytes.Buffer{}
  183. for _, r := range srs.getAllowRules() {
  184. buf.WriteString(r.String())
  185. buf.WriteString(";")
  186. }
  187. for _, r := range srs.getDenyRules() {
  188. buf.WriteString(r.String())
  189. buf.WriteString(";")
  190. }
  191. return buf.String()
  192. }