From 351e2cc38a0ebcb7dc5d4ee236a4ab71a5ce379d Mon Sep 17 00:00:00 2001 From: lvyangyang Date: Wed, 23 Dec 2020 14:47:14 +0800 Subject: [PATCH] feat(region): azure tags --- pkg/multicloud/azure/azure.go | 34 ++++++++++++++++++++++++++ pkg/multicloud/azure/host.go | 3 +++ pkg/multicloud/azure/instance.go | 15 ++++++++++++ pkg/multicloud/azure/shell/instance.go | 30 +++++++++++++++++++++++ 4 files changed, 82 insertions(+) diff --git a/pkg/multicloud/azure/azure.go b/pkg/multicloud/azure/azure.go index 9168c04d9c..26f157c762 100644 --- a/pkg/multicloud/azure/azure.go +++ b/pkg/multicloud/azure/azure.go @@ -373,6 +373,9 @@ func (self *SAzureClient) _apiVersion(resource string, params url.Values) string } info := strings.Split(strings.ToLower(resource), "/") if utils.IsInStringArray("microsoft.compute", info) { + if utils.IsInStringArray("tags", info) { + return "2020-06-01" + } if utils.IsInStringArray("publishers", info) { return "2020-06-01" } @@ -898,3 +901,34 @@ func (self *SAzureClient) GetCapabilities() []string { } return caps } + +type TagParams struct { + Properties TagProperties `json:"properties"` +} + +type TagProperties struct { + Tags map[string]string `json:"tags"` +} + +func (self *SAzureClient) GetTags(resourceId string) (map[string]string, error) { + path := fmt.Sprintf("/%s/providers/Microsoft.Resources/tags/default", resourceId) + tags := &TagParams{} + err := self.get(path, nil, tags) + if err != nil { + return nil, errors.Wrap(err, "self.get(path, nil, tags)") + } + return tags.Properties.Tags, nil +} + +func (self *SAzureClient) SetTags(resourceId string, tags map[string]string) (jsonutils.JSONObject, error) { + //reserved prefix 'microsoft', 'azure', 'windows'. + for k := range tags { + if strings.HasPrefix(k, "microsoft") || strings.HasPrefix(k, "azure") || strings.HasPrefix(k, "windows") { + return nil, errors.Wrap(cloudprovider.ErrNotSupported, "reserved prefix microsoft, azure, windows") + } + } + path := fmt.Sprintf("/%s/providers/Microsoft.Resources/tags/default", resourceId) + input := TagParams{} + input.Properties.Tags = tags + return self.put(path, jsonutils.Marshal(input)) +} diff --git a/pkg/multicloud/azure/host.go b/pkg/multicloud/azure/host.go index 0d682d8648..ce87d7f5ff 100644 --- a/pkg/multicloud/azure/host.go +++ b/pkg/multicloud/azure/host.go @@ -156,6 +156,9 @@ func (self *SRegion) _createVM(desc *cloudprovider.SManagedVMCreateConfig, nicId } params.Add(jsonutils.Marshal(linuxConfiguration), "Properties", "OsProfile", "LinuxConfiguration") } + if len(desc.Tags) > 0 { + params.Add(jsonutils.Marshal(desc.Tags), "tags") + } dataDisks := jsonutils.NewArray() for i := 0; i < len(desc.DataDisks); i++ { diff --git a/pkg/multicloud/azure/instance.go b/pkg/multicloud/azure/instance.go index f39b4e6cb6..ab3db3b5b0 100644 --- a/pkg/multicloud/azure/instance.go +++ b/pkg/multicloud/azure/instance.go @@ -953,3 +953,18 @@ func (self *SInstance) SaveImage(opts *cloudprovider.SaveImageOptions) (cloudpro } return image, nil } + +func (self *SInstance) SetMetadata(tags map[string]string, replace bool) error { + if !replace { + for k, v := range self.Tags { + if _, ok := tags[k]; !ok { + tags[k] = v + } + } + } + _, err := self.host.zone.region.client.SetTags(self.ID, tags) + if err != nil { + return errors.Wrapf(err, "self.host.zone.region.client.SetTags(%s,%s)", self.ID, jsonutils.Marshal(tags).String()) + } + return nil +} diff --git a/pkg/multicloud/azure/shell/instance.go b/pkg/multicloud/azure/shell/instance.go index 676286feb2..265bbefdcb 100644 --- a/pkg/multicloud/azure/shell/instance.go +++ b/pkg/multicloud/azure/shell/instance.go @@ -17,6 +17,7 @@ package shell import ( "context" "fmt" + "strings" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/multicloud/azure" @@ -217,4 +218,33 @@ func init() { return nil }) + shellutils.R(&InstanceOptions{}, "instance-get-tags", "get intance tags", func(cli *azure.SRegion, args *InstanceOptions) error { + tags, err := cli.GetClient().GetTags(args.ID) + if err != nil { + return err + } + printObject(tags) + return nil + }) + + type InstanceSetTagsOptions struct { + ID string `help:"Instance ID"` + Tags []string + } + shellutils.R(&InstanceSetTagsOptions{}, "instance-set-tags", "get intance metadata", func(cli *azure.SRegion, args *InstanceSetTagsOptions) error { + tags := map[string]string{} + for i := range args.Tags { + splited := strings.Split(args.Tags[i], "=") + if len(splited) == 2 { + tags[splited[0]] = splited[1] + } + } + result, err := cli.GetClient().SetTags(args.ID, tags) + if err != nil { + return err + } + printObject(result) + return nil + }) + }