简体   繁体   English

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

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

Here I'm writing a python program to list all the ec2 instances without the tag "Owner".在这里,我正在编写一个 python 程序来列出所有没有标签“所有者”的 ec2 实例。 Where I'm stuck right now is if the program encounters any Instance already having the "Owner" tag then it exits without checking further Instances.我现在卡住的地方是,如果程序遇到任何已经具有“所有者”标签的实例,那么它会退出而不检查进一步的实例。 What I want is to skip those instances and continue to check other instances.我想要的是跳过这些实例并继续检查其他实例。 Here is my Code:这是我的代码:

    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']

Here is how the json dict object would look like:下面是 json dict 对象的样子:

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

I noticed a couple of things in your code that if you did them slightly different maybe it would be easier to control the program's flow.我注意到你的代码中有几件事,如果你做的稍微不同,也许会更容易控制程序的流程。 For starters, use more descriptive variable names, if you have a list of instances for example, a good name would simply be instances .对于初学者,使用更具描述性的变量名称,例如,如果您有一个实例列表,一个好的名称就是instances Here is an example of how you could do this:以下是如何执行此操作的示例:

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

Notice how I also added some spacing to increase readability.请注意我还添加了一些间距以提高可读性。

Lastly, if you have a string, namely "Owner" , it would be silly to put thin into a variable called owner , since that would only be confusing if it were ever changed.最后,如果您有一个字符串,即"Owner" ,将 Thin 放入一个名为owner的变量中是很愚蠢的,因为只有在更改它时才会令人困惑。

Your continue is causing a few problems.您的continue导致一些问题。

Here's an alternate version:这是一个替代版本:

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'])

You are exiting the loop after finding the first tag that does not match.您在找到第一个不匹配的标签后退出循环。 Get all the tag and then check.获取所有标签,然后检查。 Try this:试试这个:

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']

having just written almost exactly this there are few areas that were over looked here.刚刚写的几乎完全相同,这里很少有区域被过度查看。 In no particular order:没有特定的顺序:

  1. The examples given will only cover one region.给出的例子将只涵盖一个地区。
  2. The examples will only find instance that are missing an owner tag, There is the case where the Tag exists, but the Value is empty示例只会找到缺少所有者标签的实例,存在标签存在但值为空的情况
  3. In the case of newly launched instance, with no Tags added, the answer examples will error out.对于新启动的实例,没有添加标签,答案示例会出错。

Below answers the question, and covers the points above.下面回答了这个问题,并涵盖了以上几点。

#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