使用TAG標籤對雲伺服器ECS的分組和管理

祝犁發表於2017-02-02

本篇是使用OpenApi管理雲伺服器的管理篇第5篇。在這一篇中,主要是利用TAG進行資源分組,只有清晰的分組才可以方便的進行未來的運維和管理。

本篇主要涉及到下面的幾個關鍵API:

TAG資源分組

很多的使用者在使用雲伺服器的時候都通過雲伺服器的名稱和描述資訊來進行資源分組,這裡的弊端是一個雲資源只支援一個名稱和描述。批量管理雲伺服器的時候一個重要的任務就是資源分組。為了方便的資源管理,雲伺服器有一個重要的概念就是TAG。TAG有下面幾個約定:

  • TAG和傳統的TAG不太一樣,TAG支援的是Key-Value的模式,可以同時指定。
  • TAG支援 ECS 的例項、磁碟、快照、映象、安全組上。
  • 每個資源最多可以繫結 10 個 Tag。
  • 如果要繫結 Tag 的 Key 在指定的資源上已經存在,則覆蓋 Value。

為了體驗TAG的功能,您可以在ECS控制檯試用體驗下。通過OpenApi可以方便的進行TAG的建立和變更。

繫結TAG到雲資源上

繫結Tag到資源上,需要指定資源的Id和資源型別,目前支援的image、instance、snapshot、disk、securitygroup。

def add_tag_to_resource(resource_id, resource_type, tag_key, tag_value):
    request = AddTagsRequest()
    request.set_ResourceId(resource_id)
    request.set_ResourceType(resource_type)
    request.set_Tag1Key(tag_key)
    request.set_Tag1Value(tag_value)
    _send_request(request)

如下面的操作就在一個ECS例項上做了兩個TAG分組,一個是ecs-console, 一個是 ecs-console-pre.

    instance_id = `i-1111`
    tag_key = `ecs-console`
    tag_value = `product`
    resource_type = `instance`
    add_tag_to_resource(instance_id, resource_type, tag_key, tag_value)
    add_tag_to_resource(instance_id, resource_type, tag_key + `-pre`, tag_value)

對於同一個key,如果設定了兩個value,第二個就會覆蓋第一個。下面的操作就只會新增成功一組key value。

    instance_id = `i-1111`
    tag_key = `ecs-console`
    tag_value = `product`
    resource_type = `instance`
    add_tag_to_resource(instance_id, resource_type, tag_key, tag_value)
    add_tag_to_resource(instance_id, resource_type, tag_key, tag_value + `-pre`)
查詢繫結的TAG

TAG的查詢可以直接完成。例如對ECS的例項可以通過查詢例項列表來實現。

def describe_instance_tags(instance_id):
    request = DescribeInstancesRequest()
    request.set_InstanceIds(json.dumps([instance_id]))
    response = _send_request(request)
    if response is not None:
        instance_list = response.get(`Instances`).get(`Instance`)
        if len(instance_list) > 0:
            instance_detail = instance_list[0]
            if instance_detail.get(`Tags`) is not None:
                return instance_detail.get(`Tags`).get(`Tag`)

通過直接查詢Tags可以快速的查詢出多個組合維度的資源。可以通過給組合的TAG完成您的應用的高度定製。例如預發環境加上pre的標籤,生產環境使用product等等來方便的管理資源。

我們也提供了查詢標籤的功能方便的進行多維度的搜尋。

def describe_tags(tag_key=None, tag_value=None, resource_type=None, resource_id=None):
    request = DescribeTagsRequest()
    if resource_type is not None:
        request.set_ResourceType(resource_type)
    if resource_id is not None:
        request.set_ResourceId(resource_id)
    if tag_key is not None:
        request.set_Tag1Key(tag_key)
    if tag_value is not None:
        request.set_Tag1Value(tag_value)
    response = _send_request(request)
    return response.get(`Tags`).get(`Tag`)

查詢返回的內容如下:

[{u`TagKey`: u`ecs-console-pre`, u`TagValue`: u`product`}, {u`TagKey`: u`ecs-console`, u`TagValue`: u`product`}]
刪除繫結的TAG

除了可以覆蓋TAG之外,也可以方便的刪除TAG。刪除TAG需要指定資源id,資源型別。可以指定TAG,直接刪除TAG下面的所有Values。也可以只刪除一組的Key,Value.

def remove_tag_from_resource(resource_id, resource_type, tag_key, tag_value=None):
    request = RemoveTagsRequest()
    request.set_ResourceId(resource_id)
    request.set_Tag1Key(tag_key)
    request.set_ResourceType(resource_type)
    if tag_value is not None:
        request.set_Tag1Value(tag_value)
    _send_request(request)

總結

靈活的使用TAG,您可以方便的完成應用分組。通過TAG來區分您的測試、預發、生產、壓測以及彈性環境的區分。方便的進行批量的資源操作。

完整程式碼如下

#  coding=utf-8

# if the python sdk is not install using `sudo pip install aliyun-python-sdk-ecs`
# if the python sdk is install using `sudo pip install --upgrade aliyun-python-sdk-ecs`
# make sure the sdk version is 2.1.2, you can use command `pip show aliyun-python-sdk-ecs` to check

import json
import logging

from aliyunsdkcore import client
from aliyunsdkecs.request.v20140526.AddTagsRequest import AddTagsRequest
from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
from aliyunsdkecs.request.v20140526.DescribeTagsRequest import DescribeTagsRequest
from aliyunsdkecs.request.v20140526.RemoveTagsRequest import RemoveTagsRequest

# configuration the log output formatter, if you want to save the output to file,
# append ",filename=`ecs_invoke.log`" after datefmt.

logging.basicConfig(level=logging.INFO,
                    format=`%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s`,
                    datefmt=`%a, %d %b %Y %H:%M:%S`)

clt = client.AcsClient(`Your Access Key Id`, `Your Access Key Secrect`, `cn-beijing`)

def add_tag_to_resource(resource_id, resource_type, tag_key, tag_value):
    ```
    add tag to resource
    :param resource_id: it can be instance id ,disk id
    :param resource_type: support image、instance、snapshot、disk、securitygroup
    :param tag_key: tag`s key
    :param tag_value: tag`s value
    :return:
    ```
    ```
    :param resource_id:
    :param resource_type:
    :param tag_key:
    :param tag_value:
    :return:
    ```
    request = AddTagsRequest()
    request.set_ResourceId(resource_id)
    request.set_ResourceType(resource_type)
    request.set_Tag1Key(tag_key)
    request.set_Tag1Value(tag_value)
    _send_request(request)


def remove_tag_from_resource(resource_id, resource_type, tag_key, tag_value=None):
    ```
    remove tag from resource
    :param resource_id: required. it can be instance id ,disk id.
    :param resource_type: support image、instance、snapshot、disk、securitygroup
    :param tag_key: tag key to remove
    :param tag_value: tag value to remove
    :return:
    ```
    request = RemoveTagsRequest()
    request.set_ResourceId(resource_id)
    request.set_Tag1Key(tag_key)
    request.set_ResourceType(resource_type)
    if tag_value is not None:
        request.set_Tag1Value(tag_value)
    _send_request(request)


def describe_tags(tag_key=None, tag_value=None, resource_type=None, resource_id=None):
    ```
    describe resource group according tag query condition.
    :param tag_key: 
    :param tag_value: 
    :param resource_type: 
    :param resource_id: 
    :return:
    ```
    request = DescribeTagsRequest()
    if resource_type is not None:
        request.set_ResourceType(resource_type)
    if resource_id is not None:
        request.set_ResourceId(resource_id)
    if tag_key is not None:
        request.set_Tag1Key(tag_key)
    if tag_value is not None:
        request.set_Tag1Value(tag_value)
    response = _send_request(request)
    return response.get(`Tags`).get(`Tag`)


def describe_instance_tags(instance_id):
    request = DescribeInstancesRequest()
    request.set_InstanceIds(json.dumps([instance_id]))
    response = _send_request(request)
    if response is not None:
        instance_list = response.get(`Instances`).get(`Instance`)
        if len(instance_list) > 0:
            instance_detail = instance_list[0]
            if instance_detail.get(`Tags`) is not None:
                return instance_detail.get(`Tags`).get(`Tag`)


# send open api request
def _send_request(request):
    request.set_accept_format(`json`)
    try:
        response_str = clt.do_action(request)
        logging.info(response_str)
        response_detail = json.loads(response_str)
        return response_detail
    except Exception as e:
        logging.error(e)


if __name__ == `__main__`:
    logging.info("Manager ECS by OpenApi!")
    instance_id = `i-1111`
    tag_key = `ecs-console`
    tag_value = `product`
    resource_type = `instance`
    add_tag_to_resource(instance_id, resource_type, tag_key, tag_value)
    add_tag_to_resource(instance_id, resource_type, tag_key + `-pre`, tag_value)
    logging.info(describe_instance_tags(instance_id))
    remove_tag_from_resource(instance_id, resource_type, tag_key)
    logging.info(describe_instance_tags(instance_id))
    describe_tags(resource_id=instance_id)


相關文章