feat(region): add tags implement

This commit is contained in:
lvyangyang
2020-12-28 16:11:04 +08:00
parent 2b47be47b0
commit 8641e9232b
5 changed files with 189 additions and 5 deletions
+47
View File
@@ -104,6 +104,7 @@ type SInstance struct {
ServiceAccounts []ServiceAccount
Scheduling map[string]interface{}
CpuPlatform string
Labels map[string]string
LabelFingerprint string
StartRestricted bool
DeletionProtection bool
@@ -665,6 +666,11 @@ func (region *SRegion) _createVM(zone string, desc *cloudprovider.SManagedVMCrea
},
"disks": disks,
}
if len(desc.Tags) > 0 {
params["labels"] = desc.Tags
}
if tags, ok := secgroups[SECGROUP_TYPE_TAG]; ok && len(tags) > 0 {
for i := range tags {
tags[i] = strings.ToLower(tags[i])
@@ -906,3 +912,44 @@ func (self *SInstance) SaveImage(opts *cloudprovider.SaveImageOptions) (cloudpro
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "no valid system disk found")
}
func (self *SInstance) GetTags() (map[string]string, error) {
return self.Labels, nil
}
func (self *SInstance) GetSysTags() map[string]string {
data := map[string]string{}
data["SecurityGroup"] = strings.Join(self.Tags.Items, ",")
return data
}
func (region *SRegion) SetLabels(id string, labels map[string]string, labelFingerprint string) error {
params := map[string]interface{}{
"labels": labels,
"labelFingerprint": labelFingerprint,
}
err := region.Do(id, "setLabels", nil, jsonutils.Marshal(params))
if err != nil {
return errors.Wrapf(err, `region.Do(%s, "setLabels", nil, %s)`, id, jsonutils.Marshal(params).String())
}
return nil
}
func (self *SInstance) SetTags(tags map[string]string, replace bool) error {
if !replace {
for k, v := range self.Labels {
if _, ok := tags[k]; !ok {
tags[k] = v
}
}
}
err := self.Refresh()
if err != nil {
return errors.Wrap(err, "self.Refresh()")
}
err = self.host.zone.region.SetLabels(self.GetId(), tags, self.LabelFingerprint)
if err != nil {
return errors.Wrapf(err, ` self.host.zone.region.SsetLabels()`)
}
return nil
}
+24
View File
@@ -16,6 +16,7 @@ package shell
import (
"fmt"
"strings"
"yunion.io/x/pkg/errors"
@@ -203,4 +204,27 @@ func init() {
return nil
})
type InstanceSetTagsOptions struct {
ID string `help:"Instance ID"`
Tags []string
}
shellutils.R(&InstanceSetTagsOptions{}, "instance-set-tags", "get intance metadata", func(cli *google.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]
}
}
instance, err := cli.GetInstance(args.ID)
if err != nil {
return errors.Wrap(err, "cli.GetInstance")
}
err = cli.SetLabels(args.ID, tags, instance.LabelFingerprint)
if err != nil {
return err
}
return nil
})
}
+4 -4
View File
@@ -183,7 +183,7 @@ func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudpr
desc.Description, desc.Account,
desc.Password, desc.DataDisks,
desc.PublicKey, desc.ExternalSecgroupId,
desc.UserData, desc.BillingCycle, desc.ProjectId)
desc.UserData, desc.BillingCycle, desc.ProjectId, desc.Tags)
if err != nil {
return nil, err
}
@@ -203,7 +203,7 @@ func (self *SHost) GetIHostNics() ([]cloudprovider.ICloudHostNetInterface, error
func (self *SHost) _createVM(name string, imgId string, sysDisk cloudprovider.SDiskInfo, cpu int, memMB int, instanceType string,
networkId string, ipAddr string, desc string, account string, passwd string,
diskSizes []cloudprovider.SDiskInfo, publicKey string, secgroupId string,
userData string, bc *billing.SBillingCycle, projectId string) (string, error) {
userData string, bc *billing.SBillingCycle, projectId string, tags map[string]string) (string, error) {
net := self.zone.getNetworkById(networkId)
if net == nil {
return "", fmt.Errorf("invalid network ID %s", networkId)
@@ -272,7 +272,7 @@ func (self *SHost) _createVM(name string, imgId string, sysDisk cloudprovider.SD
// 创建实例
if len(instanceType) > 0 {
log.Debugf("Try instancetype : %s", instanceType)
vmId, err := self.zone.region.CreateInstance(name, imgId, instanceType, networkId, secgroupId, net.VpcID, self.zone.GetId(), desc, disks, ipAddr, keypair, publicKey, passwd, userData, bc, projectId)
vmId, err := self.zone.region.CreateInstance(name, imgId, instanceType, networkId, secgroupId, net.VpcID, self.zone.GetId(), desc, disks, ipAddr, keypair, publicKey, passwd, userData, bc, projectId, tags)
if err != nil {
log.Errorf("Failed for %s: %s", instanceType, err)
return "", fmt.Errorf("create %s failed:%s", instanceType, ErrMessage(err))
@@ -294,7 +294,7 @@ func (self *SHost) _createVM(name string, imgId string, sysDisk cloudprovider.SD
for _, instType := range instanceTypes {
instanceTypeId := instType.Name
log.Debugf("Try instancetype : %s", instanceTypeId)
vmId, err = self.zone.region.CreateInstance(name, imgId, instanceTypeId, networkId, secgroupId, net.VpcID, self.zone.GetId(), desc, disks, ipAddr, keypair, publicKey, passwd, userData, bc, projectId)
vmId, err = self.zone.region.CreateInstance(name, imgId, instanceTypeId, networkId, secgroupId, net.VpcID, self.zone.GetId(), desc, disks, ipAddr, keypair, publicKey, passwd, userData, bc, projectId, tags)
if err != nil {
log.Errorf("Failed for %s: %s", instanceTypeId, err)
} else {
+82 -1
View File
@@ -291,6 +291,79 @@ func (self *SInstance) GetSysTags() map[string]string {
return data
}
func (self *SInstance) GetTags() (map[string]string, error) {
tags := map[string]string{}
for _, kv := range self.Tags {
splited := strings.Split(kv, "=")
if len(splited) == 2 {
tags[splited[0]] = splited[1]
}
}
return tags, nil
}
// https://support.huaweicloud.com/api-ecs/ecs_02_1002.html
// key 相同时value不会替换
func (self *SRegion) CreateServerTags(instanceId string, tags map[string]string) error {
params := map[string]interface{}{
"action": "create",
}
tagsObj := []map[string]string{}
for k, v := range tags {
tagsObj = append(tagsObj, map[string]string{"key": k, "value": v})
}
params["tags"] = tagsObj
_, err := self.ecsClient.Servers.PerformAction2("tags/action", instanceId, jsonutils.Marshal(params), "")
return err
}
// https://support.huaweicloud.com/api-ecs/ecs_02_1003.html
func (self *SRegion) DeleteServerTags(instanceId string, tagsKey []string) error {
params := map[string]interface{}{
"action": "delete",
}
tagsObj := []map[string]string{}
for _, k := range tagsKey {
tagsObj = append(tagsObj, map[string]string{"key": k})
}
params["tags"] = tagsObj
_, err := self.ecsClient.Servers.PerformAction2("tags/action", instanceId, jsonutils.Marshal(params), "")
return err
}
func (self *SInstance) SetTags(tags map[string]string, replace bool) error {
existedTags, err := self.GetTags()
if err != nil {
return errors.Wrap(err, "self.GetTags()")
}
deleteTagsKey := []string{}
for k := range existedTags {
if replace {
deleteTagsKey = append(deleteTagsKey, k)
} else {
if _, ok := tags[k]; ok {
deleteTagsKey = append(deleteTagsKey, k)
}
}
}
if len(deleteTagsKey) > 0 {
err := self.host.zone.region.DeleteServerTags(self.GetId(), deleteTagsKey)
if err != nil {
return errors.Wrapf(err, "self.host.zone.region.DeleteServerTags(%s,%s)", self.GetId(), deleteTagsKey)
}
}
if len(tags) > 0 {
err := self.host.zone.region.CreateServerTags(self.GetId(), tags)
if err != nil {
return errors.Wrapf(err, "self.host.zone.region.CreateServerTags(%s,%s)", self.GetId(), jsonutils.Marshal(tags).String())
}
}
return nil
}
func (self *SInstance) GetBillingType() string {
// https://support.huaweicloud.com/api-ecs/zh-cn_topic_0094148849.html
// charging_mode “0”:按需计费 “1”:按包年包月计费
@@ -824,7 +897,7 @@ type ServerTag struct {
*/
func (self *SRegion) CreateInstance(name string, imageId string, instanceType string, SubnetId string,
securityGroupId string, vpcId string, zoneId string, desc string, disks []SDisk, ipAddr string,
keypair string, publicKey string, passwd string, userData string, bc *billing.SBillingCycle, projectId string) (string, error) {
keypair string, publicKey string, passwd string, userData string, bc *billing.SBillingCycle, projectId string, tags map[string]string) (string, error) {
params := SServerCreate{}
params.AvailabilityZone = zoneId
params.Name = name
@@ -885,6 +958,14 @@ func (self *SRegion) CreateInstance(name string, imageId string, instanceType st
params.UserData = userData
}
if len(tags) > 0 {
serverTags := []ServerTag{}
for k, v := range tags {
serverTags = append(serverTags, ServerTag{Key: k, Value: v})
}
params.ServerTags = serverTags
}
serverObj := jsonutils.Marshal(params)
createParams := jsonutils.NewDict()
createParams.Add(serverObj, "server")
+32
View File
@@ -17,6 +17,7 @@ package shell
import (
"context"
"fmt"
"strings"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud/huawei"
@@ -190,4 +191,35 @@ func init() {
return nil
})
type InstanceSetTagsOptions struct {
ID string `help:"Instance ID"`
Tags []string
}
shellutils.R(&InstanceSetTagsOptions{}, "instance-set-tags", "get intance metadata", func(cli *huawei.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]
}
}
err := cli.CreateServerTags(args.ID, tags)
if err != nil {
return err
}
return nil
})
type InstanceDelTagsOptions struct {
ID string `help:"Instance ID"`
Tags []string
}
shellutils.R(&InstanceDelTagsOptions{}, "instance-del-tags", "del intance metadata", func(cli *huawei.SRegion, args *InstanceDelTagsOptions) error {
err := cli.DeleteServerTags(args.ID, args.Tags)
if err != nil {
return err
}
return nil
})
}