1

Python を使用して Azure の各リソースにタグを作成したいと考えています。

ドキュメントにこのモジュールがあります: 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: サブスクリプション リソース タグ リストの作成: サブスクリプション リソース タグのリストの取得

リソースではなく、リソースグループに対してのみタグ操作を行うことができるようですか?

例:

リソース グループにタグを追加するには: Set-AzureRmResourceGroup リソースにタグを追加します: Set-AzureRmResource

編集:

非常にきちんとしたAPIルックアップコードをありがとう。しかし、手動で配置した古い API も機能するはずです。少し変更してコードを試しました (Azure SDK が異なる可能性があります。私は 2.0.0rc5 を使用しています)。API関数を追加した後(非常に役立ちます)、残念ながら同じエラーがまだあります。

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)

エラー トレースバック (最新の呼び出しが最後): ファイル "C:\Python35-32\Scripts\Azure\temp.py"、56 行目、parameters=resource ファイル "C:\Python35-32\lib\site-packages\azure \mgmt\resource\resources\operations\resources_operations.py"、408 行目、create_or_update raise exp msrestazure.azure_exceptions.CloudError: Operation failed with status: 'Bad Request'. 詳細: 400 クライアント エラー: URL の要求が正しくありません: https://management.azure.com/subscriptions/ - -***-*****-********/resourcegroups/Build/providers/Microsoft .Web/sites/build-dev?api-version=2016-03-01

さらに作業を進めたところ、次の方法で create_or_update メソッドを使用できることがわかりました。

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

また、コード例の応答エラー メッセージには、「パラメーター プロパティに無効な値があります」と表示されます。したがって、 parameters=resource を修正する必要があると推測しています。私はそれをもっと見ていきます。

更新(解決済み!):

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 の場合、リクエストはそれを好まない。{} である必要があります。

助けてくれてありがとうトラヴィス!Azure SDK に取り組んでいるので、さらに質問を投稿します ;)

4

1 に答える 1

6

Python SDK を使用している場合は、通常、そのリソースのcreate_or_updateメソッドを使用してリソースにタグを追加できます。これらのメソッドは、parameters通常、関心のあるリソースのオブジェクト タイプであるというオブジェクトを受け取ります。ここにタグがあります。

たとえば、仮想ネットワークにタグを付けるには:

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)

azure network vnet set -t {tags}さらに、(この例では)コマンドを使用して、Xplat-Cli を介してリソースにタグを付けることができます。

を使用してリソース グループにタグを付け、 を使用azure group set -t {tags}してリソースに一般的にタグを付けることができazure resource set -t {tags}ます。

うまくいけば、それは役に立ちます。

更新 (2016 年 8 月 26 日)

API バージョンを取得するのは難しい場合があります。一般的なリソース オブジェクトの一部だと思うかもしれませんが、何らかの理由でそうではありません。ただし、次のようにしてみてください。

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 オブジェクトのページ化されたリストを提供します。投稿した方法では、リソース グループを 1 つずつループしてから、各リソース グループ内のリソースをループしました。これで問題なく動作し、ID からリソース グループ名を抽出する必要がなくなりますが、このソリューションの方が少しすっきりしていると思います。

このresolve_resource_apiメソッドは、プロバイダーの名前空間とリソース ID のリソース タイプを使用して、リソース プロバイダーの get 操作を使用して、そのリソース タイプで使用可能な API バージョンを検索します。このコード (いくつかの検証が欠けています) は、プレビュー バージョンではない最新の API バージョンを取得します (それが利用可能な唯一のバージョンでない限り)。バージョンを文字列で任意に指定するだけでは、通常は機能しません。リソースごとに API バージョンが異なるためです。

また、コードで親パスに '' が指定されているため、これは通常、子リソースでは機能しません。

于 2016-08-17T15:24:39.303 に答える