| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- // Copyright 2019 Yunion
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package qcloud
- import (
- "fmt"
- "strings"
- "yunion.io/x/cloudmux/pkg/cloudprovider"
- "yunion.io/x/log"
- "yunion.io/x/pkg/errors"
- "yunion.io/x/pkg/util/secrules"
- )
- type ServiceTemplateSpecification struct {
- ServiceId string // 协议端口ID,例如:ppm-f5n1f8da。
- ServiceGroupId string // 协议端口组ID,例如:ppmg-f5n1f8da。
- }
- func (self *ServiceTemplateSpecification) GetGlobalId() string {
- return self.ServiceId + self.ServiceGroupId
- }
- type AddressTemplateSpecification struct {
- AddressId string // IP地址ID,例如:ipm-2uw6ujo6。
- AddressGroupId string // IP地址组ID,例如:ipmg-2uw6ujo6。
- }
- func (self *AddressTemplateSpecification) GetGlobalId() string {
- return self.AddressId + self.AddressGroupId
- }
- type SecurityGroupRule struct {
- secgroup *SSecurityGroup
- Direction secrules.TSecurityRuleDirection
- PolicyIndex int // 安全组规则索引号。
- Protocol string // 协议, 取值: TCP,UDP, ICMP。
- Port string // 端口(all, 离散port, range)。
- ServiceTemplate ServiceTemplateSpecification // 协议端口ID或者协议端口组ID。ServiceTemplate和Protocol+Port互斥。
- CidrBlock string // 网段或IP(互斥)。
- Ipv6CidrBlock string
- SecurityGroupId string // 已绑定安全组的网段或IP。
- AddressTemplate AddressTemplateSpecification // IP地址ID或者ID地址组ID。
- Action string // ACCEPT 或 DROP。
- PolicyDescription string // 安全组规则描述。
- }
- func (self *SecurityGroupRule) GetGlobalId() string {
- return fmt.Sprintf("%s-%d", self.Direction, self.PolicyIndex)
- }
- func (self *SecurityGroupRule) GetAction() secrules.TSecurityRuleAction {
- if self.Action == "DROP" {
- return secrules.SecurityRuleDeny
- }
- return secrules.SecurityRuleAllow
- }
- func (self *SecurityGroupRule) GetDescription() string {
- return self.PolicyDescription
- }
- func (self *SecurityGroupRule) GetDirection() secrules.TSecurityRuleDirection {
- return self.Direction
- }
- func (self *SecurityGroupRule) GetCIDRs() []string {
- ret := []string{self.CidrBlock + self.SecurityGroupId + self.Ipv6CidrBlock + self.AddressTemplate.GetGlobalId()}
- return ret
- }
- func (self *SecurityGroupRule) GetProtocol() string {
- if len(self.Protocol) == 0 {
- return self.ServiceTemplate.GetGlobalId()
- }
- if self.Protocol == "ALL" {
- return secrules.PROTO_ANY
- }
- return strings.ToLower(self.Protocol)
- }
- func (self *SecurityGroupRule) GetPorts() string {
- if len(self.ServiceTemplate.GetGlobalId()) > 0 {
- return self.ServiceTemplate.GetGlobalId()
- }
- if self.Port == "ALL" {
- return ""
- }
- return self.Port
- }
- func (self *SecurityGroupRule) GetPriority() int {
- return self.PolicyIndex
- }
- func (self *SecurityGroupRule) Delete() error {
- return self.secgroup.region.DeleteSecgroupRule(self.secgroup.SecurityGroupId, self.GetDirection(), self.PolicyIndex)
- }
- func (self *SRegion) DeleteSecgroupRule(secId string, direction secrules.TSecurityRuleDirection, index int) error {
- params := map[string]string{
- "SecurityGroupId": secId,
- }
- switch direction {
- case secrules.DIR_IN:
- params["SecurityGroupPolicySet.Ingress.0.PolicyIndex"] = fmt.Sprintf("%d", index)
- case secrules.DIR_OUT:
- params["SecurityGroupPolicySet.Egress.0.PolicyIndex"] = fmt.Sprintf("%d", index)
- }
- _, err := self.vpcRequest("DeleteSecurityGroupPolicies", params)
- return errors.Wrapf(err, "DeleteSecurityGroupPolicies")
- }
- type SecurityGroupPolicySet struct {
- Version string
- Egress []SecurityGroupRule // 出站规则。
- Ingress []SecurityGroupRule // 入站规则。
- }
- func (self *SRegion) GetSecurityGroupRules(secGroupId string) ([]SecurityGroupRule, error) {
- params := make(map[string]string)
- params["Region"] = self.Region
- params["SecurityGroupId"] = secGroupId
- body, err := self.vpcRequest("DescribeSecurityGroupPolicies", params)
- if err != nil {
- log.Errorf("DescribeSecurityGroupAttribute fail %s", err)
- return nil, err
- }
- policies := SecurityGroupPolicySet{}
- err = body.Unmarshal(&policies, "SecurityGroupPolicySet")
- if err != nil {
- return nil, errors.Wrapf(err, "body.Unmarshal")
- }
- ret := []SecurityGroupRule{}
- for i := range policies.Egress {
- policies.Egress[i].Direction = secrules.DIR_OUT
- ret = append(ret, policies.Egress[i])
- }
- for i := range policies.Ingress {
- policies.Ingress[i].Direction = secrules.DIR_IN
- ret = append(ret, policies.Ingress[i])
- }
- return ret, nil
- }
- func (self *SecurityGroupRule) Update(opts *cloudprovider.SecurityGroupRuleUpdateOptions) error {
- return self.secgroup.region.UpdateSecurityGroupRule(self.secgroup.SecurityGroupId, self.PolicyIndex, self.GetDirection(), opts)
- }
- func (self *SRegion) UpdateSecurityGroupRule(groupId string, idx int, direction secrules.TSecurityRuleDirection, opts *cloudprovider.SecurityGroupRuleUpdateOptions) error {
- params := map[string]string{
- "SecurityGroupId": groupId,
- }
- prefix := "SecurityGroupPolicySet.Ingress.0."
- if direction == secrules.DIR_OUT {
- prefix = "SecurityGroupPolicySet.Egress.0."
- }
- if len(opts.Ports) == 0 || opts.Protocol == secrules.PROTO_ANY {
- opts.Ports = "all"
- }
- if opts.Protocol == secrules.PROTO_ANY {
- opts.Protocol = "ALL"
- }
- action := "ACCEPT"
- if opts.Action == secrules.SecurityRuleDeny {
- action = "DROP"
- }
- params[prefix+"PolicyIndex"] = fmt.Sprintf("%d", idx)
- params[prefix+"Protocol"] = strings.ToUpper(opts.Protocol)
- params[prefix+"Port"] = opts.Ports
- params[prefix+"CidrBlock"] = opts.CIDR
- params[prefix+"Action"] = action
- params[prefix+"PolicyDescription"] = opts.Desc
- _, err := self.vpcRequest("ReplaceSecurityGroupPolicy", params)
- return err
- }
|