Azure SDK Python:标记特定资源 [英] Azure SDK Python: tag a particular resource

查看:61
本文介绍了Azure SDK Python:标记特定资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用python在Azure中的每个资源上创建标签.

I want to create tag on each resource in Azure using python.

我在文档中看到了这个模块:

I see this module in the docs: http://azure-sdk-for-python.readthedocs.io/en/latest/ref/azure.mgmt.resource.resources.operations.html#azure.mgmt.resource.resources.operations.TagsOperations

create_or_update:创建订阅资源标签list:获取订阅资源标签的列表

create_or_update: Create a subscription resource tag list: Get a list of subscription resource tags

好像我只能对资源组执行标签操作,而不能对资源进行标签操作?

示例:

要将标签添加到资源组:Set-AzureRmResourceGroup将标签添加到资源:Set-AzureRmResource

To add a tag to a resource group: Set-AzureRmResourceGroup add tags to a resource: Set-AzureRmResource

非常感谢api查找代码.但是我相信我手动放置的旧api也应该起作用.我稍加修改就尝试了您的代码(我们可能有不同的Azure SDK,我使用的是2.0.0rc5).添加api函数(非常有帮助)后,不幸的是我仍然遇到相同的错误.

Thanks for the api lookup code, very neat. But I believe the old api that I manually put should also work. I tried your code with little modification(we might have different Azure SDK, I am using 2.0.0rc5). After adding the api function(very helpful), I still have the same error unfortunately.

from azure.common.credentials import UserPassCredentials
from azure.mgmt.resource.resources import ResourceManagementClient

def resolve_resource_api(client, resource):
    """ This method retrieves the latest non-preview api version for
    the given resource (unless the preview version is the only available
    api version) """
    provider = client.providers.get(resource.id.split('/')[6])
    rt = next((t for t in provider.resource_types
               if t.resource_type == '/'.join(resource.type.split('/')[1:])), None)
    #print(rt)
    if rt and 'api_versions' in rt.__dict__:
        #api_version = [v for v in rt[0].api_versions if 'preview' not in v.lower()]
        #return npv[0] if npv else rt[0].api_versions[0]
        api_version = [v for v in rt.__dict__['api_versions'] if 'preview' not in v.lower()]
        return api_version[0] if api_version else rt.__dict__['api_versions'][0]

credentials = UserPassCredentials(
    '****@****.com',    # Your new user
    '******',  # Your password
)

subscription_id= '*****-***-****-****-*******'

resource_client = ResourceManagementClient(credentials,
                                                    subscription_id)

for resource in resource_client.resources.list():
    #print(resource)
    #print(resolve_resource_api(resource_client, resource))
    if resource.id.split('/')[4] == 'Build':
        #resource.tags = {'foo':'bar'}
        if resource.type == 'Microsoft.Web/sites':
            print('resource.id: ', resource.id)
            print('resource_group_name: ', resource.id.split('/')[4])
            print('resource_provider_namespace: ', resource.id.split('/')[6])
            print('parent_resource_path: ', '')
            print('resource_type: ', str(resource.type).split('/')[-1])
            print('resource_name: ', resource.name)
            print('api_version: ', resolve_resource_api(resource_client, resource))
            resource.tags['test'] = 'test1'

            #print(resolve_resource_api(resource_client, resource))
            #continue
            print(resource)
            resource_client.resources.create_or_update(
                resource_group_name= resource.id.split('/')[4], # Extract from resource.id
                resource_provider_namespace=resource.id.split('/')[6], # Extract from resource.id
                parent_resource_path='', # Extract from resource.id
                resource_type=str(resource.type).split('/')[-1], # Extract from resource type
                resource_name=resource.name,
                api_version=resolve_resource_api(resource_client, resource),
                parameters=resource
                )
        print('-'*10)

错误追溯(最近一次通话):在第56行的"C:\ Python35-32 \ Scripts \ Azure \ temp.py"文件中参数=资源文件"C:\ Python35-32 \ lib \ site-packages \ azure \ mgmt \ resource \ resources \ operations \ resources_operations.py",行408,在create_or_update中提高经验msrestazure.azure_exceptions.CloudError:操作失败,状态:错误请求".详细信息:400客户端错误:网址请求错误: https://management.azure.com/subscriptions/ - -***-*****-*******/resourcegroups/Build/providers/Microsoft.Web/sites/build-dev?api-version = 2016-03-01

Error Traceback (most recent call last): File "C:\Python35-32\Scripts\Azure\temp.py", line 56, in parameters=resource File "C:\Python35-32\lib\site-packages\azure\mgmt\resource\resources\operations\resources_operations.py", line 408, in create_or_update raise exp msrestazure.azure_exceptions.CloudError: Operation failed with status: 'Bad Request'. Details: 400 Client Error: Bad Request for url: https://management.azure.com/subscriptions/--***-*****-*******/resourcegroups/Build/providers/Microsoft.Web/sites/build-dev?api-version=2016-03-01

我做了更多工作,发现我可以通过以下方式使用create_or_update方法:

I worked more and found the I am able to use the create_or_update method in the following way:

from azure.mgmt.resource.resources.models import GenericResource
parameters=GenericResource(
        location='West US',
        properties={},
    )

代码示例的响应错误消息显示参数属性具有无效值".所以我猜参数=资源需要固定.我将对此进行更多的研究.

And the response error message with your code example says that "The parameter properties has an invalid value". So I am guessing parameters=resource needs to be fixed. I will look more into that.

更新(已解决!):

for resource in resource_client.resources.list():
    #print(resource)
    if resource.id.split('/')[4] == 'Build':
        if resource.type == 'Microsoft.Web/sites':
            print('resource.id: ', resource.id)
            print('resource_group_name: ', resource.id.split('/')[4])
            print('resource_provider_namespace: ', resource.id.split('/')[6])
            print('parent_resource_path: ', '')
            print('resource_type: ', str(resource.type).split('/')[-1])
            print('resource_name: ', resource.name)
            print('api_version: ', resolve_resource_api(resource_client, resource))
            if not resource.tags:
                resource.tags = {}
                resource.tags['test'] = 'test1'
            else:
                resource.tags['test'] = 'test1'

            # This solves the error 400 Client Error: Bad Request. The parameter properties has an invalid value. 
            if not resource.properties:
                resource.properties = {}

            resource_client.resources.create_or_update(
                resource_group_name= resource.id.split('/')[4], # Extract from resource.id
                resource_provider_namespace=resource.id.split('/')[6], # Extract from resource.id
                parent_resource_path='', # Extract from resource.id
                resource_type=str(resource.type).split('/')[-1], # Extract from resource type
                resource_name=resource.name,
                api_version=resolve_resource_api(resource_client, resource),
                parameters=resource,
                )
        print('-'*10)

出于某种奇怪的原因,如果resource.properties为None,则请求不喜欢它.它必须是{}.

感谢您对Travis的帮助!在使用Azure SDK时,我将发布更多问题;)

Thank you for your help Travis! I will post more questions as I work on Azure SDK ;)

推荐答案

如果使用的是Python SDK,通常可以使用该资源的 create_or_update 方法向该资源添加标签.这些方法采用一个称为 parameters 的对象,该对象通常是您感兴趣的资源的对象类型.在这里可以找到标签.

If you are using the Python SDK, you can generally add tags to a resource using that resource's create_or_update method. These methods take an object called parameters which is generally the object type of the resource you are interested in. This is where you will find tags.

例如标记虚拟网络:

from azure.mgmt.network.models import VirtualNetwork

vnet = client.virtual_networks.get(resource_group_name, vnet_name)
vnet.tags = {'a':'b'}
client.virtual_networks.create_or_update(resource_group_name, virtual_network_name, vnet)

此外,您还可以使用Xcode-Cli使用 azure network vnet set -t {tags} 命令通过Xplat-Cli标记资源.

Additionally, you can tag your resource through Xplat-Cli using (for this example) the azure network vnet set -t {tags} command.

您可以使用 azure group set -t {tags} 标记资源组,并通常使用 azure resource set -t {tags} 标记资源.

You can tag resource groups using azure group set -t {tags} and resources generically using azure resource set -t {tags}.

希望这会有所帮助.

更新(8/26/16)

获取API版本可能很棘手.您可能会认为它只是通用资源对象的一部分,但由于某种原因,它不是.但是,请尝试如下操作:

Getting API versions can be tricky. You would think it would just be part of the generic resource object, but for some reason it's not. However, try something like this:

from azure.common.credentials import UserPassCredentials
from azure.mgmt.resource.resources import ResourceManagementClient

def resolve_resource_api(client, resource):
    """ This method retrieves the latest non-preview api version for
    the given resource (unless the preview version is the only available
    api version) """
    provider = client.providers.get(resource.id.split('/')[6])
    rt = next((t for t in provider.resource_types if t.resource_type == resource.type), None)
    if rt and len(rt) == 1 and rt[0].api_versions:
        api_version = [v for v in rt[0].api_versions if 'preview' not in v.lower()]
        return npv[0] if npv else rt[0].api_versions[0]

credentials = UserPassCredentials(
    '****@****.com',    # Your new user
    '******',  # Your password
)

subscription_id= '*****-***-****-****-*******'

resource_client = ResourceManagementClient(credentials, subscription_id)

for resource in resource_client.resources.list():
    resource.tags['test'] = 'test1'

    # avoid error 400 if properties must be set
    if not resource.properties:
        resource.properties = {}

    resource_client.resources.create_or_update(
        resource_group_name= resource.id.split('/')[4],
        resource_provider_namespace=resource.id.split('/')[6],
        parent_resource_path='', # WARNING: this will not work with child resources
        resource_type=str(resource.type).split('/')[-1],
        resource_name=resource.name,
        api_version=resolve_resource_api(resource_client, resource),
        parameters=resource
    )

client.resources下的list操作给出了整个订阅的GenericResource对象的分页列表.发布的方式是一个接一个地遍历资源组,然后遍历每个资源组中的资源.这样就可以正常工作,并且可以避免您不得不从ID中提取资源组名称,但是我认为这种解决方案更干净一些.

The list operation under client.resources gives a paged list of GenericResource objects for the entire subscription. The way you posted, you looped through the resource groups one by one and then through the resources within each resource group. That will work just fine, and it will avoid you having to extract the resource group name from the ID, but I think this solution is a little cleaner.

resolve_resource_api 方法使用提供程序名称空间和资源ID中的资源类型,通过资源提供程序get操作查找该资源类型的可用API版本.此代码(缺少某些验证)将检索不是预览版本的最新API版本(除非这是唯一可用的版本).通常,只是随意指定字符串中的版本是行不通的,因为不同的资源将具有不同的API版本.

The resolve_resource_api method uses the provider namespace and the resource type from the resource ID to look up the available API versions for that resource type using the resource provider get operation. This code (which is missing some validation) will retrieve the most recent API versions that is not a preview version (unless that is the only version available). Just arbitrarily specifying a version in a string is not going to work generally, as the different resources will have different API versions.

此外,您的代码为父路径指定了'',因此通常不适用于子资源.

Also, your code specifies '' for parent path, so this would not work generally for a child resource.

这篇关于Azure SDK Python:标记特定资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆