secrules.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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 ctyun
  15. import (
  16. "strings"
  17. "time"
  18. "yunion.io/x/cloudmux/pkg/cloudprovider"
  19. "yunion.io/x/pkg/errors"
  20. "yunion.io/x/pkg/util/netutils"
  21. "yunion.io/x/pkg/util/secrules"
  22. "yunion.io/x/pkg/utils"
  23. )
  24. type SSecurityGroupRule struct {
  25. secgroup *SSecurityGroup
  26. Direction string
  27. Priority int
  28. Ethertype string
  29. Protocol string
  30. DestCidrIP string
  31. Description string
  32. Origin string
  33. CreateTime time.Time
  34. Id string
  35. Action string
  36. SecurityGroupId string
  37. Range string
  38. }
  39. func (self *SSecurityGroupRule) GetGlobalId() string {
  40. return self.Id
  41. }
  42. func (self *SSecurityGroupRule) GetDirection() secrules.TSecurityRuleDirection {
  43. if self.Direction == "egress" {
  44. return secrules.DIR_OUT
  45. }
  46. return secrules.DIR_IN
  47. }
  48. func (self *SSecurityGroupRule) GetPriority() int {
  49. return self.Priority
  50. }
  51. func (self *SSecurityGroupRule) GetAction() secrules.TSecurityRuleAction {
  52. if self.Action == "accept" {
  53. return secrules.SecurityRuleAllow
  54. }
  55. return secrules.SecurityRuleDeny
  56. }
  57. func (self *SSecurityGroupRule) GetProtocol() string {
  58. return strings.ToLower(self.Protocol)
  59. }
  60. func (self *SSecurityGroupRule) GetPorts() string {
  61. if strings.ToLower(self.Range) == "any" {
  62. return ""
  63. }
  64. return self.Range
  65. }
  66. func (self *SSecurityGroupRule) GetDescription() string {
  67. return self.Description
  68. }
  69. func (self *SSecurityGroupRule) GetCIDRs() []string {
  70. return []string{self.DestCidrIP}
  71. }
  72. func (self *SSecurityGroupRule) Delete() error {
  73. err := self.secgroup.region.DeleteSecgroupRule(self.SecurityGroupId, self.Id, self.GetDirection())
  74. if err != nil {
  75. return errors.Wrapf(err, "Delete")
  76. }
  77. // wait rule deleted
  78. cloudprovider.Wait(time.Second*5, time.Minute, func() (bool, error) {
  79. secgroup, err := self.secgroup.region.GetSecurityGroup(self.secgroup.Id)
  80. if err != nil {
  81. return false, nil
  82. }
  83. for _, rule := range secgroup.SecurityGroupRuleList {
  84. if rule.Id == self.Id {
  85. return false, nil
  86. }
  87. }
  88. return true, nil
  89. })
  90. return nil
  91. }
  92. func (self *SRegion) CreateSecurityGroupRule(groupId string, opts *cloudprovider.SecurityGroupRuleCreateOptions) error {
  93. rule := map[string]interface{}{
  94. "direction": "egress",
  95. "action": "accept",
  96. "priority": opts.Priority,
  97. "protocol": strings.ToUpper(opts.Protocol),
  98. "ethertype": "IPv4",
  99. "destCidrIp": opts.CIDR,
  100. "description": opts.Desc,
  101. "range": "1-65535",
  102. }
  103. if _, err := netutils.NewIPV6Prefix(opts.CIDR); err == nil {
  104. rule["ethertype"] = "IPv6"
  105. }
  106. api := "/v4/vpc/create-security-group-egress"
  107. if opts.Direction == secrules.DIR_IN {
  108. rule["direction"] = "ingress"
  109. api = "/v4/vpc/create-security-group-ingress"
  110. }
  111. if len(opts.Ports) > 0 {
  112. rule["range"] = opts.Ports
  113. }
  114. if opts.Action == secrules.SecurityRuleDeny {
  115. rule["action"] = "drop"
  116. }
  117. params := map[string]interface{}{
  118. "securityGroupID": groupId,
  119. "clientToken": utils.GenRequestId(20),
  120. "securityGroupRules": []map[string]interface{}{rule},
  121. }
  122. _, err := self.post(SERVICE_VPC, api, params)
  123. return err
  124. }
  125. func (self *SRegion) DeleteSecgroupRule(groupId, ruleId string, direction secrules.TSecurityRuleDirection) error {
  126. params := map[string]interface{}{
  127. "securityGroupID": groupId,
  128. "securityGroupRuleID": ruleId,
  129. "clientToken": utils.GenRequestId(20),
  130. }
  131. api := "/v4/vpc/revoke-security-group-egress"
  132. if direction == secrules.DIR_IN {
  133. api = "/v4/vpc/revoke-security-group-ingress"
  134. }
  135. _, err := self.post(SERVICE_VPC, api, params)
  136. return err
  137. }
  138. func (self *SSecurityGroupRule) Update(opts *cloudprovider.SecurityGroupRuleUpdateOptions) error {
  139. return self.secgroup.region.UpdateSecurityGroupRule(self.secgroup.Id, self.Id, self.GetDirection(), opts)
  140. }
  141. func (self *SRegion) UpdateSecurityGroupRule(groupId, id string, direction secrules.TSecurityRuleDirection, opts *cloudprovider.SecurityGroupRuleUpdateOptions) error {
  142. api := "/v4/vpc/modify-security-group-egress"
  143. if direction == secrules.DIR_IN {
  144. api = "/v4/vpc/modify-security-group-ingress"
  145. }
  146. params := map[string]interface{}{
  147. "securityGroupID": groupId,
  148. "securityGroupRuleID": id,
  149. "description": opts.Desc,
  150. "clientToken": utils.GenRequestId(20),
  151. }
  152. _, err := self.post(SERVICE_VPC, api, params)
  153. return err
  154. }