| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346 |
- // Copyright 2023 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 volcengine
- import (
- "fmt"
- "strings"
- "time"
- "yunion.io/x/cloudmux/pkg/cloudprovider"
- "yunion.io/x/cloudmux/pkg/multicloud"
- "yunion.io/x/jsonutils"
- "yunion.io/x/log"
- "yunion.io/x/pkg/errors"
- "yunion.io/x/pkg/util/secrules"
- "yunion.io/x/pkg/utils"
- )
- type SSecurityGroup struct {
- multicloud.SSecurityGroup
- VolcEngineTags
- region *SRegion
- Description string
- SecurityGroupId string
- SecurityGroupName string
- VpcId string
- CreationTime time.Time
- UpdateTime time.Time
- Type string
- ProjectName string
- ServiceManaged bool
- Status string
- }
- func (region *SRegion) CreateSecurityGroup(opts *cloudprovider.SecurityGroupCreateInput) (string, error) {
- params := make(map[string]string)
- params["VpcId"] = opts.VpcId
- params["SecurityGroupName"] = opts.Name
- if len(opts.ProjectId) > 0 {
- params["ProjectName"] = opts.ProjectId
- }
- if len(opts.Desc) > 0 {
- params["Description"] = opts.Desc
- }
- params["ClientToken"] = utils.GenRequestId(20)
- idx := 1
- for k, v := range opts.Tags {
- params[fmt.Sprintf("Tags.%d.Key", idx)] = k
- params[fmt.Sprintf("Tags.%d.Value", idx)] = v
- idx++
- }
- body, err := region.vpcRequest("CreateSecurityGroup", params)
- if err != nil {
- return "", errors.Wrap(err, "CreateSecurityGroup")
- }
- return body.GetString("SecurityGroupId")
- }
- func (region *SRegion) GetSecurityGroup(secGroupId string) (*SSecurityGroup, error) {
- secgroups, _, err := region.GetSecurityGroups("", "", []string{secGroupId}, 1, 1)
- if err != nil {
- return nil, err
- }
- for i := range secgroups {
- secgroups[i].region = region
- if secgroups[i].SecurityGroupId == secGroupId {
- return &secgroups[i], nil
- }
- }
- return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%s", secGroupId)
- }
- func (region *SRegion) GetSecurityGroupRules(secGroupId string) ([]SSecurityGroupRule, error) {
- params := make(map[string]string)
- params["SecurityGroupId"] = secGroupId
- body, err := region.vpcRequest("DescribeSecurityGroupAttributes", params)
- if err != nil {
- return nil, err
- }
- ret := []SSecurityGroupRule{}
- err = body.Unmarshal(&ret, "Permissions")
- if err != nil {
- return nil, errors.Wrapf(err, "Unmarshal security group details fail")
- }
- return ret, nil
- }
- func (self *SSecurityGroup) CreateRule(opts *cloudprovider.SecurityGroupRuleCreateOptions) (cloudprovider.ISecurityGroupRule, error) {
- err := self.region.CreateSecurityGroupRule(self.SecurityGroupId, opts)
- if err != nil {
- return nil, err
- }
- rules, err := self.region.GetSecurityGroupRules(self.SecurityGroupId)
- if err != nil {
- return nil, err
- }
- for i := range rules {
- rules[i].secgroup = self
- if rules[i].GetPriority() == opts.Priority &&
- rules[i].GetAction() == opts.Action &&
- rules[i].GetProtocol() == opts.Protocol &&
- rules[i].GetPorts() == opts.Ports &&
- strings.Join(rules[i].GetCIDRs(), ",") == opts.CIDR &&
- rules[i].GetDirection() == opts.Direction {
- return &rules[i], nil
- }
- }
- return nil, errors.Wrapf(cloudprovider.ErrNotFound, "after created")
- }
- func (region *SRegion) CreateSecurityGroupRule(secGrpId string, opts *cloudprovider.SecurityGroupRuleCreateOptions) error {
- params := make(map[string]string)
- params["RegionId"] = region.RegionId
- params["SecurityGroupId"] = secGrpId
- params["Description"] = opts.Desc
- params["PortStart"] = "-1"
- params["PortEnd"] = "-1"
- if len(opts.Ports) > 0 {
- params["PortStart"] = opts.Ports
- params["PortEnd"] = opts.Ports
- if strings.Contains(opts.Ports, "-") {
- info := strings.Split(opts.Ports, "-")
- if len(info) == 2 {
- params["PortStart"] = info[0]
- params["PortEnd"] = info[1]
- }
- }
- }
- protocol := opts.Protocol
- if len(opts.Protocol) == 0 || opts.Protocol == secrules.PROTO_ANY {
- protocol = "all"
- }
- params["Protocol"] = protocol
- params["Policy"] = "drop"
- if opts.Action == secrules.SecurityRuleAllow {
- params["Policy"] = "accept"
- }
- params["CidrIp"] = "0.0.0.0/0"
- if len(opts.CIDR) > 0 {
- params["CidrIp"] = opts.CIDR
- }
- params["Priority"] = fmt.Sprintf("%d", opts.Priority)
- action := "AuthorizeSecurityGroupIngress"
- if opts.Direction == secrules.DIR_OUT {
- action = "AuthorizeSecurityGroupEgress"
- }
- _, err := region.vpcRequest(action, params)
- return err
- }
- func (region *SRegion) GetSecurityGroups(vpcId, name string, securityGroupIds []string, pageSize int, pageNumber int) ([]SSecurityGroup, int, error) {
- if pageSize > 100 || pageSize <= 0 {
- pageSize = 100
- }
- params := make(map[string]string)
- params["PageSize"] = fmt.Sprintf("%d", pageSize)
- params["PageNumber"] = fmt.Sprintf("%d", pageNumber)
- if len(vpcId) > 0 {
- params["VpcId"] = vpcId
- }
- if len(name) > 0 {
- params["SecurityGroupName"] = name
- }
- for i, id := range securityGroupIds {
- params[fmt.Sprintf("SecurityGroupIds.%d", i+1)] = id
- }
- body, err := region.vpcRequest("DescribeSecurityGroups", params)
- if err != nil {
- log.Errorf("GetSecurityGroups fail %s", err)
- return nil, 0, err
- }
- secgrps := make([]SSecurityGroup, 0)
- err = body.Unmarshal(&secgrps, "SecurityGroups")
- if err != nil {
- log.Errorf("Unmarshal security groups fail %s", err)
- return nil, 0, err
- }
- total, _ := body.Int("TotalCount")
- return secgrps, int(total), nil
- }
- func (secgroup *SSecurityGroup) GetId() string {
- return secgroup.SecurityGroupId
- }
- func (secgroup *SSecurityGroup) GetName() string {
- return secgroup.SecurityGroupName
- }
- func (secgroup *SSecurityGroup) GetGlobalId() string {
- return secgroup.GetId()
- }
- func (secgroup *SSecurityGroup) GetCreatedAt() time.Time {
- return secgroup.CreationTime
- }
- func (secgroup *SSecurityGroup) GetDescription() string {
- return secgroup.Description
- }
- func (secgroup *SSecurityGroup) GetStatus() string {
- return secgroup.Status
- }
- func (secgroup *SSecurityGroup) Refresh() error {
- group, err := secgroup.region.GetSecurityGroup(secgroup.GetId())
- if err != nil {
- return err
- }
- return jsonutils.Update(secgroup, group)
- }
- func (secgroup *SSecurityGroup) GetProjectId() string {
- return secgroup.ProjectName
- }
- func (self *SRegion) vpcTagResources(resType string, id string, tags map[string]string) error {
- if len(tags) == 0 {
- return nil
- }
- params := map[string]string{
- "ResourceType": resType,
- "ResourceIds.1": id,
- }
- idx := 1
- for k, v := range tags {
- params[fmt.Sprintf("Tags.%d.Key", idx)] = k
- params[fmt.Sprintf("Tags.%d.Value", idx)] = v
- idx++
- }
- _, err := self.vpcRequest("TagResources", params)
- return err
- }
- func (self *SRegion) vpcUntagResources(resType string, id string, tags map[string]string) error {
- if len(tags) == 0 {
- return nil
- }
- params := map[string]string{
- "ResourceType": resType,
- "ResourceIds.1": id,
- }
- idx := 1
- for k := range tags {
- params[fmt.Sprintf("TagKeys.%d", idx)] = k
- idx++
- }
- _, err := self.vpcRequest("UntagResources", params)
- return err
- }
- func (secgroup *SSecurityGroup) SetTags(tags map[string]string, replace bool) error {
- oldTags, err := secgroup.GetTags()
- if err != nil {
- return errors.Wrapf(err, "GetTags")
- }
- added, removed := map[string]string{}, map[string]string{}
- for k, v := range tags {
- oldValue, ok := oldTags[k]
- if !ok {
- added[k] = v
- } else if oldValue != v {
- removed[k] = oldValue
- added[k] = v
- }
- }
- if replace {
- for k, v := range oldTags {
- newValue, ok := tags[k]
- if !ok {
- removed[k] = v
- } else if v != newValue {
- added[k] = newValue
- removed[k] = v
- }
- }
- }
- if len(removed) > 0 {
- err = secgroup.region.vpcUntagResources("securitygroup", secgroup.SecurityGroupId, removed)
- if err != nil {
- return errors.Wrapf(err, "DeleteTags %s", removed)
- }
- }
- if len(added) > 0 {
- return secgroup.region.vpcTagResources("securitygroup", secgroup.SecurityGroupId, added)
- }
- return nil
- }
- func (secgroup *SSecurityGroup) GetRules() ([]cloudprovider.ISecurityGroupRule, error) {
- rules, err := secgroup.region.GetSecurityGroupRules(secgroup.SecurityGroupId)
- if err != nil {
- return nil, err
- }
- ret := []cloudprovider.ISecurityGroupRule{}
- for i := range rules {
- rules[i].secgroup = secgroup
- ret = append(ret, &rules[i])
- }
- return ret, nil
- }
- func (secgroup *SSecurityGroup) GetVpcId() string {
- return secgroup.VpcId
- }
- func (secgroup *SSecurityGroup) GetReferences() ([]cloudprovider.SecurityGroupReference, error) {
- ret := []cloudprovider.SecurityGroupReference{}
- return ret, errors.Wrapf(errors.ErrNotImplemented, "GetReferences not supported")
- }
- func (region *SRegion) DeleteSecurityGroup(id string) error {
- params := make(map[string]string)
- params["SecurityGroupId"] = id
- _, err := region.vpcRequest("DeleteSecurityGroup", params)
- if err != nil {
- return errors.Wrapf(err, "Delete %s", id)
- }
- return nil
- }
- func (secgroup *SSecurityGroup) Delete() error {
- return secgroup.region.DeleteSecurityGroup(secgroup.SecurityGroupId)
- }
|