| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- // 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"
- "time"
- "yunion.io/x/jsonutils"
- "yunion.io/x/pkg/errors"
- "yunion.io/x/pkg/util/netutils"
- "yunion.io/x/pkg/util/secrules"
- api "yunion.io/x/cloudmux/pkg/apis/compute"
- "yunion.io/x/cloudmux/pkg/cloudprovider"
- "yunion.io/x/cloudmux/pkg/multicloud"
- )
- type SSecurityGroup struct {
- multicloud.SSecurityGroup
- QcloudTags
- region *SRegion
- SecurityGroupId string // 安全组实例ID,例如:sg-ohuuioma。
- SecurityGroupName string // 安全组名称,可任意命名,但不得超过60个字符。
- SecurityGroupDesc string // 安全组备注,最多100个字符。
- ProjectId string // 项目id,默认0。可在qcloud控制台项目管理页面查询到。
- IsDefault bool // 是否是默认安全组,默认安全组不支持删除。
- CreatedTime time.Time // 安全组创建时间。
- SecurityGroupPolicySet SecurityGroupPolicySet
- }
- func (self *SRegion) GetSecurityGroups(ids []string, name string, offset int, limit int) ([]SSecurityGroup, int, error) {
- if limit > 100 || limit <= 0 {
- limit = 100
- }
- params := make(map[string]string)
- params["Limit"] = fmt.Sprintf("%d", limit)
- params["Offset"] = fmt.Sprintf("%d", offset)
- if len(name) > 0 {
- params["Filters.0.Name"] = "security-group-name"
- params["Filters.0.Values.0"] = name
- }
- for idx, id := range ids {
- params[fmt.Sprintf("SecurityGroupIds.%d", idx)] = id
- }
- resp, err := self.vpcRequest("DescribeSecurityGroups", params)
- if err != nil {
- return nil, 0, errors.Wrapf(err, "DescribeSecurityGroups")
- }
- secgrps := make([]SSecurityGroup, 0)
- err = resp.Unmarshal(&secgrps, "SecurityGroupSet")
- if err != nil {
- return nil, 0, errors.Wrapf(err, "resp.Unmarshal")
- }
- total, _ := resp.Float("TotalCount")
- return secgrps, int(total), nil
- }
- func (self *SSecurityGroup) GetVpcId() string {
- return ""
- }
- func (self *SSecurityGroup) GetId() string {
- return self.SecurityGroupId
- }
- func (self *SSecurityGroup) GetGlobalId() string {
- return self.SecurityGroupId
- }
- func (self *SSecurityGroup) GetDescription() string {
- return self.SecurityGroupDesc
- }
- func (self *SSecurityGroup) SetTags(tags map[string]string, replace bool) error {
- return self.region.SetResourceTags("cvm", "sg", []string{self.SecurityGroupId}, tags, replace)
- }
- func (self *SSecurityGroup) GetName() string {
- if len(self.SecurityGroupName) > 0 {
- return self.SecurityGroupName
- }
- return self.SecurityGroupId
- }
- type ReferredSecurityGroup struct {
- SecurityGroupId string
- ReferredSecurityGroupIds []string
- }
- func (self *SSecurityGroup) GetReferences() ([]cloudprovider.SecurityGroupReference, error) {
- references, err := self.region.DescribeSecurityGroupReferences(self.SecurityGroupId)
- if err != nil {
- return nil, errors.Wrapf(err, "DescribeSecurityGroupReferences")
- }
- ret := []cloudprovider.SecurityGroupReference{}
- for _, refer := range references {
- if refer.SecurityGroupId == self.SecurityGroupId {
- for _, id := range refer.ReferredSecurityGroupIds {
- ret = append(ret, cloudprovider.SecurityGroupReference{
- Id: id,
- })
- }
- }
- }
- return ret, nil
- }
- func (self *SRegion) DescribeSecurityGroupReferences(id string) ([]ReferredSecurityGroup, error) {
- params := map[string]string{
- "Region": self.Region,
- "SecurityGroupIds.0": id,
- }
- resp, err := self.vpcRequest("DescribeSecurityGroupReferences", params)
- if err != nil {
- return nil, errors.Wrapf(err, "DescribeSecurityGroupReferences")
- }
- ret := []ReferredSecurityGroup{}
- err = resp.Unmarshal(&ret, "ReferredSecurityGroupSet")
- if err != nil {
- return nil, errors.Wrapf(err, "resp.Unmarshal")
- }
- return ret, nil
- }
- func (self *SSecurityGroup) GetRules() ([]cloudprovider.ISecurityGroupRule, error) {
- rules, err := self.region.GetSecurityGroupRules(self.SecurityGroupId)
- if err != nil {
- return nil, errors.Wrapf(err, "GetSecurityGroupRules")
- }
- ret := []cloudprovider.ISecurityGroupRule{}
- for i := range rules {
- rules[i].secgroup = self
- ret = append(ret, &rules[i])
- }
- return ret, nil
- }
- func (self *SSecurityGroup) GetStatus() string {
- return api.SECGROUP_STATUS_READY
- }
- func (self *SSecurityGroup) Refresh() error {
- group, err := self.region.GetSecurityGroup(self.SecurityGroupId)
- if err != nil {
- return err
- }
- return jsonutils.Update(self, group)
- }
- func (self *SRegion) GetSecurityGroup(id string) (*SSecurityGroup, error) {
- groups, _, err := self.GetSecurityGroups([]string{id}, "", 0, 1)
- if err != nil {
- return nil, err
- }
- for i := range groups {
- if groups[i].SecurityGroupId == id {
- groups[i].region = self
- return &groups[i], nil
- }
- }
- return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%s", id)
- }
- func (self *SRegion) DeleteSecurityGroup(secGroupId string) error {
- params := make(map[string]string)
- params["Region"] = self.Region
- params["SecurityGroupId"] = secGroupId
- _, err := self.vpcRequest("DeleteSecurityGroup", params)
- return err
- }
- type AddressTemplate struct {
- AddressSet []string
- AddressTemplateId string
- AddressTemplateName string
- CreatedTime time.Time
- }
- func (self *SRegion) AddressList(addressId, addressName string, offset, limit int) ([]AddressTemplate, int, error) {
- params := map[string]string{}
- filter := 0
- if len(addressId) > 0 {
- params[fmt.Sprintf("Filters.%d.Name", filter)] = "address-template-id"
- params[fmt.Sprintf("Filters.%d.Values.0", filter)] = addressId
- filter++
- }
- if len(addressName) > 0 {
- params[fmt.Sprintf("Filters.%d.Name", filter)] = "address-template-name"
- params[fmt.Sprintf("Filters.%d.Values.0", filter)] = addressName
- filter++
- }
- params["Offset"] = fmt.Sprintf("%d", offset)
- if limit == 0 {
- limit = 20
- }
- params["Limit"] = fmt.Sprintf("%d", limit)
- body, err := self.vpcRequest("DescribeAddressTemplates", params)
- if err != nil {
- return nil, 0, err
- }
- addressTemplates := []AddressTemplate{}
- err = body.Unmarshal(&addressTemplates, "AddressTemplateSet")
- if err != nil {
- return nil, 0, err
- }
- total, _ := body.Float("TotalCount")
- return addressTemplates, int(total), nil
- }
- type AddressTemplateGroup struct {
- AddressTemplateIdSet []string
- AddressTemplateGroupName string
- AddressTemplateGroupId string
- CreatedTime time.Time
- }
- func (self *SRegion) AddressGroupList(groupId, groupName string, offset, limit int) ([]AddressTemplateGroup, int, error) {
- params := map[string]string{}
- filter := 0
- if len(groupId) > 0 {
- params[fmt.Sprintf("Filters.%d.Name", filter)] = "address-template-group-id"
- params[fmt.Sprintf("Filters.%d.Values.0", filter)] = groupId
- filter++
- }
- if len(groupName) > 0 {
- params[fmt.Sprintf("Filters.%d.Name", filter)] = "address-template-group-name"
- params[fmt.Sprintf("Filters.%d.Values.0", filter)] = groupName
- filter++
- }
- params["Offset"] = fmt.Sprintf("%d", offset)
- if limit == 0 {
- limit = 20
- }
- params["Limit"] = fmt.Sprintf("%d", limit)
- body, err := self.vpcRequest("DescribeAddressTemplateGroups", params)
- if err != nil {
- return nil, 0, err
- }
- addressTemplateGroups := []AddressTemplateGroup{}
- err = body.Unmarshal(&addressTemplateGroups, "AddressTemplateGroupSet")
- if err != nil {
- return nil, 0, err
- }
- total, _ := body.Float("TotalCount")
- return addressTemplateGroups, int(total), nil
- }
- func (self *SRegion) CreateSecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (*SSecurityGroup, error) {
- params := make(map[string]string)
- params["Region"] = self.Region
- params["GroupName"] = opts.Name
- params["GroupDescription"] = opts.Desc
- if len(opts.ProjectId) > 0 {
- params["ProjectId"] = opts.ProjectId
- }
- idx := 0
- for k, v := range opts.Tags {
- params[fmt.Sprintf("Tags.%d.Key", idx)] = k
- params[fmt.Sprintf("Tags.%d.Value", idx)] = v
- idx++
- }
- secgroup := SSecurityGroup{region: self}
- body, err := self.vpcRequest("CreateSecurityGroup", params)
- if err != nil {
- return nil, errors.Wrap(err, "CreateSecurityGroup")
- }
- err = body.Unmarshal(&secgroup, "SecurityGroup")
- if err != nil {
- return nil, errors.Wrap(err, "body.Unmarshal")
- }
- return &secgroup, nil
- }
- func (self *SSecurityGroup) CreateRule(opts *cloudprovider.SecurityGroupRuleCreateOptions) (cloudprovider.ISecurityGroupRule, error) {
- rules, err := self.region.GetSecurityGroupRules(self.SecurityGroupId)
- if err != nil {
- return nil, errors.Wrapf(err, "GetSecurityGroupRules")
- }
- maxPriority := 0
- for i := range rules {
- if rules[i].GetDirection() == opts.Direction && rules[i].PolicyIndex > maxPriority {
- maxPriority = rules[i].PolicyIndex
- }
- }
- if opts.Priority > maxPriority {
- opts.Priority = maxPriority
- }
- err = self.region.CreateSecurityGroupRule(self.SecurityGroupId, opts)
- if err != nil {
- return nil, errors.Wrapf(err, "CreateSecurityGroupRule")
- }
- rules, err = self.region.GetSecurityGroupRules(self.SecurityGroupId)
- if err != nil {
- return nil, errors.Wrapf(err, "GetSecurityGroupRules")
- }
- for i := range rules {
- if rules[i].Direction == opts.Direction && rules[i].GetPriority() == opts.Priority {
- rules[i].secgroup = self
- return &rules[i], nil
- }
- }
- return nil, errors.Wrapf(cloudprovider.ErrNotFound, "after created")
- }
- func (self *SRegion) CreateSecurityGroupRule(groupId string, opts *cloudprovider.SecurityGroupRuleCreateOptions) error {
- prefix := "SecurityGroupPolicySet.Egress.0."
- if opts.Direction == secrules.DIR_IN {
- prefix = "SecurityGroupPolicySet.Ingress.0."
- }
- if opts.Protocol == secrules.PROTO_ANY {
- opts.Protocol = "all"
- opts.Ports = "all"
- }
- if len(opts.Ports) == 0 {
- opts.Ports = "all"
- }
- action := "accept"
- if opts.Action == secrules.SecurityRuleDeny {
- action = "drop"
- }
- if len(opts.CIDR) == 0 {
- opts.CIDR = "0.0.0.0/0"
- }
- params := map[string]string{
- "SecurityGroupId": groupId,
- prefix + "PolicyIndex": fmt.Sprintf("%d", opts.Priority),
- prefix + "Protocol": strings.ToUpper(opts.Protocol),
- prefix + "PolicyDescription": opts.Desc,
- prefix + "Action": action,
- prefix + "Port": opts.Ports,
- prefix + "CidrBlock": opts.CIDR,
- }
- if _, err := netutils.NewIPV6Prefix(opts.CIDR); err == nil {
- params[prefix+"Ipv6CidrBlock"] = opts.CIDR
- delete(params, prefix+"CidrBlock")
- }
- _, err := self.vpcRequest("CreateSecurityGroupPolicies", params)
- if err != nil {
- return errors.Wrapf(err, "CreateSecurityGroupPolicies")
- }
- return nil
- }
- func (self *SSecurityGroup) GetProjectId() string {
- return self.ProjectId
- }
- func (self *SSecurityGroup) Delete() error {
- return self.region.DeleteSecurityGroup(self.SecurityGroupId)
- }
|