繁体   English   中英

Python Boto3 - 无法列出没有标签的实例

[英]Python Boto3 - Unable to list Instances without tags

在这里,我正在编写一个 python 程序来列出所有没有标签“所有者”的 ec2 实例。 我现在卡住的地方是,如果程序遇到任何已经具有“所有者”标签的实例,那么它会退出而不检查进一步的实例。 我想要的是跳过这些实例并继续检查其他实例。 这是我的代码:

    import boto3
    client = boto3.client('ec2',region_name='ap-south-1')
    a = client.describe_instances()
    count=0
    y="Owner"
    for i in a['Reservations']:
       for j in i['Instances']:
         for k in range(len(j['Tags'])):
            if y == j['Tags'][k]['Key']:
               count +=1
            else:
              continue
         if count==0:
           print "The following Instance does not have Owner Tag: "+j['InstanceId']

下面是 json dict 对象的样子:

    {
     'Reservations': [{
      'Instances': [{
            .
            .
            .
            .
          'Tags':[
            {
             'Value': 'sample1',
             'Key': 'Name'
            }, 
            {
             'Value': 'user',
             'Key': 'Owner'
            }
        ]
    }
  }
}

我注意到你的代码中有几件事,如果你做的稍微不同,也许会更容易控制程序的流程。 对于初学者,使用更具描述性的变量名称,例如,如果您有一个实例列表,一个好的名称就是instances 以下是如何执行此操作的示例:

import boto3
client = boto3.client('ec2',region_name='ap-south-1')
data = client.describe_instances()
count=0

reservations = data["Reservations"]

for reservation in reservations:

    instances = reservation["Instances"]

    for instance in instances:

        tags = instance["Tags"]
        instanceId = instance['InstanceId']

        hasOwner = len([tag for tag in tags if tag["Key"] == "Owner"]) > 0

        print "The following Instance does not have Owner Tag: " + instanceId

请注意我还添加了一些间距以提高可读性。

最后,如果您有一个字符串,即"Owner" ,将 Thin 放入一个名为owner的变量中是很愚蠢的,因为只有在更改它时才会令人困惑。

您的continue导致一些问题。

这是一个替代版本:

import boto3

key_to_find = 'Owner'

client = boto3.client('ec2')

response = client.describe_instances()

for reservation in response['Reservations']:
  for instance in reservation['Instances']:
    if key_to_find not in [tag['Key'] for tag in instance['Tags']]:
      print (key_to_find + ' tag not found for Instance ' + instance['InstanceId'])

您在找到第一个不匹配的标签后退出循环。 获取所有标签,然后检查。 试试这个:

for i in a['Reservations']:
  for j in i['Instances']: # For each instance
    keys = [tag['Key'].upper() for tag in j['Tags']] # Collect all tags
    if 'OWNER' not in keys: # Case insensitive check of Owner tag
      print "The following Instance does not have Owner Tag: "+j['InstanceId']

刚刚写的几乎完全相同,这里很少有区域被过度查看。 没有特定的顺序:

  1. 给出的例子将只涵盖一个地区。
  2. 示例只会找到缺少所有者标签的实例,存在标签存在但值为空的情况
  3. 对于新启动的实例,没有添加标签,答案示例会出错。

下面回答了这个问题,并涵盖了以上几点。

#Open an initial client to get a list of existing regions
client = boto3.client('ec2', region_name='us-east-1')

# Get a list of all existing regions
zones = client.describe_regions()

# Loop through all regions as anyone can launch in any region though we all 
# tend to work in us-east-1
for region in zones["Regions"]:
    #reset a dict used for tracking to make sure we don't carry data forward
    bt_missing = {}
    region_called = region["RegionName"]
    # open a new client as we move through each region
    ec2 = boto3.client('ec2', region_name=region_called)

    # Get a list of running instances in the region
    response = ec2.describe_instances()
    
    # Loop though all instances looking for instances with No tags, Missing Billing Owner tags,
    # or empty Billing Owner tags... adding the instance-id to a list 

    for resv in response["Reservations"]:
        for inst in resv["Instances"]:
            if "Tags" not in [x for x in inst]:
                print(f"The instance: {inst['InstanceId']} has no tags at all, if your's please update: {region_called}")
                continue
            if "Billing_Owner" not in [t['Key'] for t in inst["Tags"]]:
                bt_missing.update({inst["InstanceId"]: region_called})


    for resv in response["Reservations"]:
        for inst in resv["Instances"]:
            if "Tags" not in [x for x in inst]:
                continue
            for tag in inst["Tags"]:
                if tag['Key'] == "Billing_Owner" and not tag['Value']:
                    bt_missing.update({inst["InstanceId"]: region_called})

    # Take the list of all instance-ids in all regions that have blank, or missing
    # billing owner tags or no tags at all, and retrieve the Name tag for that instance
    # and put that into a dict -- instanceid: name-region format

    # reset inst to not carry data foward
    inst = ""
    for inst in bt_missing:
        report_on = ec2.describe_tags(
            Filters=[
                {
                    'Name': 'resource-id',
                    'Values': [inst],
                },
            ],
        )

        for tag in report_on["Tags"]:
            if tag["Key"] == "Name":
                instname = tag["Value"]
        message = f"The instance: {inst} has no Billing Owner tag, if yours, please update: Name: {instname}, region: {bt_missing[inst]}"
        print(message)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM