secgrouprule.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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 qcloud
  15. import (
  16. "fmt"
  17. "strings"
  18. "yunion.io/x/cloudmux/pkg/cloudprovider"
  19. "yunion.io/x/log"
  20. "yunion.io/x/pkg/errors"
  21. "yunion.io/x/pkg/util/secrules"
  22. )
  23. type ServiceTemplateSpecification struct {
  24. ServiceId string // 协议端口ID,例如:ppm-f5n1f8da。
  25. ServiceGroupId string // 协议端口组ID,例如:ppmg-f5n1f8da。
  26. }
  27. func (self *ServiceTemplateSpecification) GetGlobalId() string {
  28. return self.ServiceId + self.ServiceGroupId
  29. }
  30. type AddressTemplateSpecification struct {
  31. AddressId string // IP地址ID,例如:ipm-2uw6ujo6。
  32. AddressGroupId string // IP地址组ID,例如:ipmg-2uw6ujo6。
  33. }
  34. func (self *AddressTemplateSpecification) GetGlobalId() string {
  35. return self.AddressId + self.AddressGroupId
  36. }
  37. type SecurityGroupRule struct {
  38. secgroup *SSecurityGroup
  39. Direction secrules.TSecurityRuleDirection
  40. PolicyIndex int // 安全组规则索引号。
  41. Protocol string // 协议, 取值: TCP,UDP, ICMP。
  42. Port string // 端口(all, 离散port, range)。
  43. ServiceTemplate ServiceTemplateSpecification // 协议端口ID或者协议端口组ID。ServiceTemplate和Protocol+Port互斥。
  44. CidrBlock string // 网段或IP(互斥)。
  45. Ipv6CidrBlock string
  46. SecurityGroupId string // 已绑定安全组的网段或IP。
  47. AddressTemplate AddressTemplateSpecification // IP地址ID或者ID地址组ID。
  48. Action string // ACCEPT 或 DROP。
  49. PolicyDescription string // 安全组规则描述。
  50. }
  51. func (self *SecurityGroupRule) GetGlobalId() string {
  52. return fmt.Sprintf("%s-%d", self.Direction, self.PolicyIndex)
  53. }
  54. func (self *SecurityGroupRule) GetAction() secrules.TSecurityRuleAction {
  55. if self.Action == "DROP" {
  56. return secrules.SecurityRuleDeny
  57. }
  58. return secrules.SecurityRuleAllow
  59. }
  60. func (self *SecurityGroupRule) GetDescription() string {
  61. return self.PolicyDescription
  62. }
  63. func (self *SecurityGroupRule) GetDirection() secrules.TSecurityRuleDirection {
  64. return self.Direction
  65. }
  66. func (self *SecurityGroupRule) GetCIDRs() []string {
  67. ret := []string{self.CidrBlock + self.SecurityGroupId + self.Ipv6CidrBlock + self.AddressTemplate.GetGlobalId()}
  68. return ret
  69. }
  70. func (self *SecurityGroupRule) GetProtocol() string {
  71. if len(self.Protocol) == 0 {
  72. return self.ServiceTemplate.GetGlobalId()
  73. }
  74. if self.Protocol == "ALL" {
  75. return secrules.PROTO_ANY
  76. }
  77. return strings.ToLower(self.Protocol)
  78. }
  79. func (self *SecurityGroupRule) GetPorts() string {
  80. if len(self.ServiceTemplate.GetGlobalId()) > 0 {
  81. return self.ServiceTemplate.GetGlobalId()
  82. }
  83. if self.Port == "ALL" {
  84. return ""
  85. }
  86. return self.Port
  87. }
  88. func (self *SecurityGroupRule) GetPriority() int {
  89. return self.PolicyIndex
  90. }
  91. func (self *SecurityGroupRule) Delete() error {
  92. return self.secgroup.region.DeleteSecgroupRule(self.secgroup.SecurityGroupId, self.GetDirection(), self.PolicyIndex)
  93. }
  94. func (self *SRegion) DeleteSecgroupRule(secId string, direction secrules.TSecurityRuleDirection, index int) error {
  95. params := map[string]string{
  96. "SecurityGroupId": secId,
  97. }
  98. switch direction {
  99. case secrules.DIR_IN:
  100. params["SecurityGroupPolicySet.Ingress.0.PolicyIndex"] = fmt.Sprintf("%d", index)
  101. case secrules.DIR_OUT:
  102. params["SecurityGroupPolicySet.Egress.0.PolicyIndex"] = fmt.Sprintf("%d", index)
  103. }
  104. _, err := self.vpcRequest("DeleteSecurityGroupPolicies", params)
  105. return errors.Wrapf(err, "DeleteSecurityGroupPolicies")
  106. }
  107. type SecurityGroupPolicySet struct {
  108. Version string
  109. Egress []SecurityGroupRule // 出站规则。
  110. Ingress []SecurityGroupRule // 入站规则。
  111. }
  112. func (self *SRegion) GetSecurityGroupRules(secGroupId string) ([]SecurityGroupRule, error) {
  113. params := make(map[string]string)
  114. params["Region"] = self.Region
  115. params["SecurityGroupId"] = secGroupId
  116. body, err := self.vpcRequest("DescribeSecurityGroupPolicies", params)
  117. if err != nil {
  118. log.Errorf("DescribeSecurityGroupAttribute fail %s", err)
  119. return nil, err
  120. }
  121. policies := SecurityGroupPolicySet{}
  122. err = body.Unmarshal(&policies, "SecurityGroupPolicySet")
  123. if err != nil {
  124. return nil, errors.Wrapf(err, "body.Unmarshal")
  125. }
  126. ret := []SecurityGroupRule{}
  127. for i := range policies.Egress {
  128. policies.Egress[i].Direction = secrules.DIR_OUT
  129. ret = append(ret, policies.Egress[i])
  130. }
  131. for i := range policies.Ingress {
  132. policies.Ingress[i].Direction = secrules.DIR_IN
  133. ret = append(ret, policies.Ingress[i])
  134. }
  135. return ret, nil
  136. }
  137. func (self *SecurityGroupRule) Update(opts *cloudprovider.SecurityGroupRuleUpdateOptions) error {
  138. return self.secgroup.region.UpdateSecurityGroupRule(self.secgroup.SecurityGroupId, self.PolicyIndex, self.GetDirection(), opts)
  139. }
  140. func (self *SRegion) UpdateSecurityGroupRule(groupId string, idx int, direction secrules.TSecurityRuleDirection, opts *cloudprovider.SecurityGroupRuleUpdateOptions) error {
  141. params := map[string]string{
  142. "SecurityGroupId": groupId,
  143. }
  144. prefix := "SecurityGroupPolicySet.Ingress.0."
  145. if direction == secrules.DIR_OUT {
  146. prefix = "SecurityGroupPolicySet.Egress.0."
  147. }
  148. if len(opts.Ports) == 0 || opts.Protocol == secrules.PROTO_ANY {
  149. opts.Ports = "all"
  150. }
  151. if opts.Protocol == secrules.PROTO_ANY {
  152. opts.Protocol = "ALL"
  153. }
  154. action := "ACCEPT"
  155. if opts.Action == secrules.SecurityRuleDeny {
  156. action = "DROP"
  157. }
  158. params[prefix+"PolicyIndex"] = fmt.Sprintf("%d", idx)
  159. params[prefix+"Protocol"] = strings.ToUpper(opts.Protocol)
  160. params[prefix+"Port"] = opts.Ports
  161. params[prefix+"CidrBlock"] = opts.CIDR
  162. params[prefix+"Action"] = action
  163. params[prefix+"PolicyDescription"] = opts.Desc
  164. _, err := self.vpcRequest("ReplaceSecurityGroupPolicy", params)
  165. return err
  166. }