securitygroup.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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 ucloud
  15. import (
  16. "fmt"
  17. "strings"
  18. "yunion.io/x/jsonutils"
  19. "yunion.io/x/pkg/errors"
  20. "yunion.io/x/pkg/util/secrules"
  21. api "yunion.io/x/cloudmux/pkg/apis/compute"
  22. "yunion.io/x/cloudmux/pkg/cloudprovider"
  23. "yunion.io/x/cloudmux/pkg/multicloud"
  24. )
  25. // https://docs.ucloud.cn/api/unet-api/describe_firewall
  26. type SSecurityGroup struct {
  27. multicloud.SSecurityGroup
  28. UcloudTags
  29. region *SRegion
  30. CreateTime int64 `json:"CreateTime"`
  31. FWID string `json:"FWId"`
  32. GroupID string `json:"GroupId"`
  33. Name string `json:"Name"`
  34. Remark string `json:"Remark"`
  35. ResourceCount int `json:"ResourceCount"`
  36. Rule []SecurityGroupRule `json:"Rule"`
  37. Tag string `json:"Tag"`
  38. Type string `json:"Type"`
  39. }
  40. func (self *SSecurityGroup) GetProjectId() string {
  41. return self.region.client.projectId
  42. }
  43. func (self *SSecurityGroup) GetId() string {
  44. return self.FWID
  45. }
  46. func (self *SSecurityGroup) GetName() string {
  47. if len(self.Name) == 0 {
  48. return self.GetId()
  49. }
  50. return self.Name
  51. }
  52. func (self *SSecurityGroup) GetGlobalId() string {
  53. return self.GetId()
  54. }
  55. func (self *SSecurityGroup) GetStatus() string {
  56. return api.SECGROUP_STATUS_READY
  57. }
  58. func (self *SSecurityGroup) Refresh() error {
  59. group, err := self.region.GetSecurityGroup(self.GetId())
  60. if err != nil {
  61. return err
  62. }
  63. return jsonutils.Update(self, group)
  64. }
  65. func (self *SSecurityGroup) GetDescription() string {
  66. return self.Remark
  67. }
  68. func (self *SSecurityGroup) GetRules() ([]cloudprovider.ISecurityGroupRule, error) {
  69. ret := []cloudprovider.ISecurityGroupRule{}
  70. for i := range self.Rule {
  71. self.Rule[i].secgroup = self
  72. ret = append(ret, &self.Rule[i])
  73. }
  74. return ret, nil
  75. }
  76. func (self *SSecurityGroup) GetVpcId() string {
  77. return ""
  78. }
  79. func (self *SRegion) GetSecurityGroup(secGroupId string) (*SSecurityGroup, error) {
  80. secgroups, err := self.GetSecurityGroups(secGroupId, "", "")
  81. if err != nil {
  82. return nil, err
  83. }
  84. for i := range secgroups {
  85. secgroups[i].region = self
  86. if secgroups[i].GetGlobalId() == secGroupId {
  87. return &secgroups[i], nil
  88. }
  89. }
  90. return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%s", secGroupId)
  91. }
  92. // https://docs.ucloud.cn/api/unet-api/create_firewall
  93. func (self *SRegion) CreateSecurityGroup(name, description string) (string, error) {
  94. params := NewUcloudParams()
  95. params.Set("Name", name)
  96. params.Set("Remark", description)
  97. rules := []string{"TCP|22|0.0.0.0/0|ACCEPT|LOW", "TCP|3389|0.0.0.0/0|ACCEPT|LOW", "ICMP||0.0.0.0/0|ACCEPT|LOW"}
  98. for i, rule := range rules {
  99. params.Set(fmt.Sprintf("Rule.%d", i), rule)
  100. }
  101. type Firewall struct {
  102. FWId string
  103. }
  104. firewall := Firewall{}
  105. err := self.DoAction("CreateFirewall", params, &firewall)
  106. if err != nil {
  107. return "", err
  108. }
  109. return firewall.FWId, nil
  110. }
  111. func (self *SSecurityGroup) CreateRule(opts *cloudprovider.SecurityGroupRuleCreateOptions) (cloudprovider.ISecurityGroupRule, error) {
  112. params := NewUcloudParams()
  113. params.Set("FWId", self.FWID)
  114. idx := 0
  115. for _, rule := range self.Rule {
  116. params.Set(fmt.Sprintf("Rule.%d", idx), rule.String())
  117. idx++
  118. }
  119. if len(opts.Ports) == 0 {
  120. opts.Ports = "1-65535"
  121. }
  122. if opts.Protocol == secrules.PROTO_ICMP || opts.Protocol == "gre" {
  123. opts.Ports = ""
  124. }
  125. if opts.Protocol == secrules.PROTO_ANY {
  126. return nil, errors.Wrapf(cloudprovider.ErrNotSupported, "protocol any")
  127. }
  128. action := "DROP"
  129. if opts.Action == secrules.SecurityRuleAllow {
  130. action = "ACCEPT"
  131. }
  132. priority := "LOW"
  133. if opts.Priority == 1 {
  134. priority = "HIGH"
  135. } else if opts.Priority == 2 {
  136. priority = "MEDIUM"
  137. }
  138. rule := fmt.Sprintf("%s|%s|%s|%s|%s|%s", strings.ToUpper(opts.Protocol), opts.Ports, opts.CIDR, action, priority, opts.Desc)
  139. params.Set(fmt.Sprintf("Rule.%d", idx), rule)
  140. err := self.region.DoAction("UpdateFirewall", params, nil)
  141. if err != nil {
  142. return nil, err
  143. }
  144. err = self.Refresh()
  145. if err != nil {
  146. return nil, err
  147. }
  148. for i := range self.Rule {
  149. if self.Rule[i].String() == rule {
  150. self.Rule[i].secgroup = self
  151. return &self.Rule[i], nil
  152. }
  153. }
  154. return nil, errors.Wrapf(cloudprovider.ErrNotFound, "after created")
  155. }
  156. func (self *SRegion) GetSecurityGroups(secGroupId string, resourceId string, name string) ([]SSecurityGroup, error) {
  157. secgroups := make([]SSecurityGroup, 0)
  158. params := NewUcloudParams()
  159. if len(secGroupId) > 0 {
  160. params.Set("FWId", secGroupId)
  161. }
  162. if len(resourceId) > 0 {
  163. params.Set("ResourceId", resourceId)
  164. params.Set("ResourceType", "uhost") // 默认只支持"uhost",云主机
  165. }
  166. err := self.DoListAll("DescribeFirewall", params, &secgroups)
  167. if err != nil {
  168. if strings.Contains(err.Error(), "not exist") {
  169. return nil, cloudprovider.ErrNotFound
  170. }
  171. return nil, err
  172. }
  173. result := []SSecurityGroup{}
  174. for i := range secgroups {
  175. if len(name) == 0 || secgroups[i].Name == name {
  176. secgroups[i].region = self
  177. result = append(result, secgroups[i])
  178. }
  179. }
  180. return result, nil
  181. }
  182. func (self *SSecurityGroup) Delete() error {
  183. return self.region.DeleteSecurityGroup(self.FWID)
  184. }