diff --git a/pkg/compute/regiondrivers/managedvirtual.go b/pkg/compute/regiondrivers/managedvirtual.go index d57118b4de..8cdf288196 100644 --- a/pkg/compute/regiondrivers/managedvirtual.go +++ b/pkg/compute/regiondrivers/managedvirtual.go @@ -265,6 +265,7 @@ func (self *SManagedVirtualizationRegionDriver) RequestSyncstatusLoadbalancer(ct if err != nil { return nil, err } + models.SyncVirtualResourceMetadata(ctx, userCred, lb, iLoadbalancer) status := iLoadbalancer.GetStatus() if utils.IsInStringArray(status, []string{api.LB_STATUS_ENABLED, api.LB_STATUS_DISABLED}) { return nil, lb.SetStatus(userCred, status, "") @@ -2846,7 +2847,7 @@ func (self *SManagedVirtualizationRegionDriver) RequestSyncElasticcacheStatus(ct if err != nil { return nil, errors.Wrap(err, "elasticcache.GetIElasticcache") } - + models.SyncVirtualResourceMetadata(ctx, userCred, elasticcache, iElasticcache) return nil, elasticcache.SetStatus(userCred, iElasticcache.GetStatus(), "syncstatus") }) return nil diff --git a/pkg/mcclient/options/loadbalancers.go b/pkg/mcclient/options/loadbalancers.go index 9892397d16..f77bc4b43d 100644 --- a/pkg/mcclient/options/loadbalancers.go +++ b/pkg/mcclient/options/loadbalancers.go @@ -29,7 +29,7 @@ type LoadbalancerCreateOptions struct { Network string Address string AddressType string `choices:"intranet|internet"` - LoadbalancerSpec string `choices:"slb.s1.small|slb.s2.small|slb.s2.medium|slb.s3.small|slb.s3.medium|slb.s3.large"` + LoadbalancerSpec string `choices:"slb.s1.small|slb.s2.small|slb.s2.medium|slb.s3.small|slb.s3.medium|slb.s3.large|network"` ChargeType string `choices:"traffic|bandwidth"` Bandwidth int Zone string diff --git a/pkg/multicloud/aws/loadbalancer.go b/pkg/multicloud/aws/loadbalancer.go index 16b6ef8126..a7ff6cec43 100644 --- a/pkg/multicloud/aws/loadbalancer.go +++ b/pkg/multicloud/aws/loadbalancer.go @@ -25,6 +25,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/pkg/errors" "yunion.io/x/pkg/utils" api "yunion.io/x/onecloud/pkg/apis/compute" @@ -124,6 +125,15 @@ func (self *SElb) GetMetadata() *jsonutils.JSONDict { metadata.Add(jsonutils.NewString(v), k) } + tags, err := self.region.FetchElbTags(self.LoadBalancerArn) + if err != nil { + log.Errorf("self.region.FetchElbTags() %s", err) + return metadata + } + for k, v := range tags { + metadata.Add(jsonutils.NewString(v), k) + } + return metadata } @@ -470,5 +480,38 @@ func (self *SRegion) CreateElbBackendgroup(group *cloudprovider.SLoadbalancerBac } func (self *SElb) SetMetadata(tags map[string]string, replace bool) error { - return cloudprovider.ErrNotSupported + oldTags, err := self.region.FetchElbTags(self.LoadBalancerArn) + if err != nil { + return errors.Wrapf(err, "self.region.FetchElbTags(%s)", self.LoadBalancerArn) + } + err = self.region.UpdateResourceTags(self.LoadBalancerArn, oldTags, tags, replace) + if err != nil { + return errors.Wrap(err, "self.region.UpdateResourceTags(self.LoadBalancerArn, oldTags, tags, replace)") + } + return nil +} + +func (self *SRegion) FetchElbTags(arn string) (map[string]string, error) { + client, err := self.GetElbV2Client() + if err != nil { + return nil, err + } + params := elbv2.DescribeTagsInput{} + params.SetResourceArns([]*string{&arn}) + output, err := client.DescribeTags(¶ms) + if err != nil { + return nil, errors.Wrapf(err, "client.DescribeTags(%s)", jsonutils.Marshal(params).String()) + } + result := map[string]string{} + for i := range output.TagDescriptions { + if output.TagDescriptions[i].ResourceArn != nil && *output.TagDescriptions[i].ResourceArn == arn { + for j := range output.TagDescriptions[i].Tags { + if output.TagDescriptions[i].Tags[j].Key != nil && output.TagDescriptions[i].Tags[j].Value != nil { + result[*output.TagDescriptions[i].Tags[j].Key] = *output.TagDescriptions[i].Tags[j].Value + } + } + return result, nil + } + } + return nil, cloudprovider.ErrNotFound } diff --git a/pkg/multicloud/aws/region.go b/pkg/multicloud/aws/region.go index 866b595972..43c96f7351 100644 --- a/pkg/multicloud/aws/region.go +++ b/pkg/multicloud/aws/region.go @@ -893,6 +893,21 @@ func (self *SRegion) CreateILoadBalancer(loadbalancer *cloudprovider.SLoadbalanc // params.SetSecurityGroups() params.SetSubnets(ConvertedList(loadbalancer.NetworkIDs)) + + tagInput := []*elbv2.Tag{} + keys := []string{} + values := []string{} + for k, v := range loadbalancer.Tags { + keys = append(keys, k) + values = append(values, v) + } + for i := range keys { + tagInput = append(tagInput, &elbv2.Tag{ + Key: &keys[i], + Value: &values[i], + }) + } + params.SetTags(tagInput) ret, err := client.CreateLoadBalancer(params) if err != nil { return nil, err diff --git a/pkg/multicloud/aws/resource_tag.go b/pkg/multicloud/aws/resource_tag.go index c80e733f49..485668fdad 100644 --- a/pkg/multicloud/aws/resource_tag.go +++ b/pkg/multicloud/aws/resource_tag.go @@ -15,6 +15,8 @@ package aws import ( + "strings" + "github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi" "yunion.io/x/jsonutils" @@ -82,3 +84,38 @@ func (self *SRegion) UntagResources(arns []string, tagKeys []string) error { } return nil } + +func (self *SRegion) UpdateResourceTags(arn string, oldTags, tags map[string]string, replace bool) error { + addTags := map[string]string{} + for k, v := range tags { + if strings.HasPrefix(k, "aws:") { + return errors.Wrap(cloudprovider.ErrNotSupported, "The aws: prefix is reserved for AWS use") + } + if _, ok := oldTags[k]; !ok { + addTags[k] = v + } else { + if oldTags[k] != v { + addTags[k] = v + } + } + } + delTags := []string{} + if replace { + for k := range oldTags { + if _, ok := tags[k]; !ok { + if !strings.HasPrefix(k, "aws:") { + delTags = append(delTags, k) + } + } + } + } + err := self.UntagResources([]string{arn}, delTags) + if err != nil { + return errors.Wrapf(err, "self.host.zone.region.UntagResources([]string{%s}, %s)", arn, jsonutils.Marshal(delTags).String()) + } + err = self.TagResources([]string{arn}, addTags) + if err != nil { + return errors.Wrapf(err, "self.host.zone.region.TagResources([]string{%s}, %s)", arn, jsonutils.Marshal(addTags).String()) + } + return nil +}