[英]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:没有特定的顺序:
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.