《云端安全守护者:深入解析阿里云EIP相关网络资源信息自动化收集与分析脚本Global_EIPResource_info_from_aliyun_v1.0.1.py》

随着云计算技术的发展,越来越多的企业选择将业务部署在云端,阿里云作为国内领先的云服务提供商之一,为企业提供了丰富的云产品和服务。为了更好地管理这些资源,自动化工具变得尤为重要。本文介绍一个使用Python编写的自动化脚本,该脚本能够帮助我们收集阿里云上的弹性公网IP(EIP)、ECS实例及VPC等资源的信息,并将这些信息整合输出为易于阅读的格式,同时保存为Excel文件,便于后续的数据分析和管理。

脚本功能概述:

配置读取:从指定的配置文件中读取阿里云的访问密钥ID和密钥
客户端初始化:根据读取到的密钥信息,初始化VPC和ECS的客户端对象
地域信息获取:动态获取阿里云支持的所有地域信息
EIP信息收集:遍历所有地域,获取每个地域内的EIP信息,包括分配ID、名称、绑定的实例ID、实例类型和IP地址
ECS实例信息收集:对于每个绑定了EIP的ECS实例,收集其实例ID、名称和VPC ID
VPC信息收集:收集与ECS实例关联的VPC信息,包括VPC ID和名称
NAT网关信息收集:对于绑定到NAT网关的EIP,收集相关的VPC信息
数据整合与输出:将收集到的信息按照指定格式打印出来,并保存为Excel文件


技术要点:

多模块协作:脚本内部使用多个函数分别处理不同的任务,如读取配置、初始化客户端、获取不同类型的资源信息等,使得代码结构清晰且易于维护。
异常处理:虽然示例中没有具体展示异常处理逻辑,但在实际开发过程中,应当考虑对API请求失败等情况进行适当的错误处理。
API调用:利用阿里云SDK中的API接口,如DescribeEipAddresses、DescribeInstances、DescribeVpcs等,来获取所需的资源信息。
数据存储:利用Pandas库将收集到的数据整理为DataFrame格式,并使用openpyxl将数据导出至Excel文件,方便后续的数据分析工作。


设计思路

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# 脚本名称: Global_EIPResource_info_from_aliyun_v1.0.1.py
# 用法: /usr/bin/python3 /data/python/aliyun/Global_EIPResource_info_from_aliyun_v1.0.1.py > /var/log/Global_EIPResource_info_from_aliyun_v1.0.1.py.log 2>&1 
# 作者: 朱鹏飞(Richard) <zhupengfei@chagee.com>
# 日期: 2024年10月14日 09:35
# 更新:2024年10月15日 11:28
# SDK 安装命令:pip3 install alibabacloud_vpc20160428==6.9.3 -i https://pypi.org/simple   && pip install alibabacloud_ecs20140526==4.4.3 -i https://pypi.org/simple && pip3 install --upgrade alibabacloud-vpc20160428  -i https://pypi.org/simple && pip3 install pandas openpyxl -i https://pypi.org/simple
# 注意事项:get_all_regions函数:使用DescribeRegions API动态获取所有可用的地域

####
### 设计可以通过以下方式实现:
 ## 1、调用DescribeEipAddresses接口获取EIP的详细信息,包括EIP的ID和绑定的实例ID。然后获取到相关绑定ECS实例ID
 ## 2、通过ECS实例ID,在调用调用DescribeInstances接口,获取ECS实例的名称和类型,以及它所在的VPC ID
 ## 3、用VPC ID调用DescribeVpcs接口,获取VPC的名称和详细信息

 ### 设计理想输出效果:
 ## 序号 实例ID/名称 IP地址 绑定实例类型/ID 专有网络

####

读取配置文件中的AK/SK

从配置文件中读取阿里云的Access Key ID和Access Key Secret,这是进行API调用的基础认证信息。通过configparser模块读取配置文件,确保了脚本能够安全地管理敏感信息

import configparser

def read_aksk_from_config():
    config = configparser.ConfigParser()
    config.read('/data/app/aliyun/aksk.ini')
    access_key_id = config['it_zpf_w']['ALIBABA_CLOUD_ACCESS_KEY_ID']
    access_key_secret = config['it_zpf_w']['ALIBABA_CLOUD_ACCESS_KEY_SECRET']
    return access_key_id, access_key_secret 

初始化客户端

在各个阿里云产品间进行API调用,初始化了VPC和ECS两个客户端对象,它们将用于后续的资源查询操作。通过传递region_id参数,确保了客户端知道要操作哪个地域的资源

from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_vpc20160428.client import Client as VpcClient
from alibabacloud_ecs20140526.client import Client as EcsClient

def init_client(region_id):
    access_key_id, access_key_secret = read_aksk_from_config()
    config = open_api_models.Config(
        access_key_id=access_key_id,
        access_key_secret=access_key_secret,
        region_id=region_id
    )
    vpc_client = VpcClient(config)
    ecs_client = EcsClient(config)
    return vpc_client, ecs_client 

获取所有可用地域

通过调用ECS产品的DescribeRegionsRequest来实现的

from alibabacloud_ecs20140526.models import DescribeRegionsRequest

def get_all_regions():
    access_key_id, access_key_secret = read_aksk_from_config()
    config = open_api_models.Config(
        access_key_id=access_key_id,
        access_key_secret=access_key_secret,
        region_id='cn-shanghai'
    )
    ecs_client = EcsClient(config)
    request = DescribeRegionsRequest()
    response = ecs_client.describe_regions(request)
    regions_info = response.body.to_map()
    return [region['RegionId'] for region in regions_info['Regions']['Region']] 

获取EIP信息

获取EIP信息是通过调用VPC产品的DescribeEipAddressesRequest实现的。这里使用了分页机制来确保可以获取所有的EIP信息
通过循环遍历直到获取不到新的数据为止,确保了所有EIP信息都被收集到

from alibabacloud_vpc20160428.models import DescribeEipAddressesRequest

def get_eip_info(vpc_client, region_id):
    eips = []
    page_number = 1
    page_size = 50
    while True:
        request = DescribeEipAddressesRequest(
            region_id=region_id,
            page_number=page_number,
            page_size=page_size
        )
        eip_response = vpc_client.describe_eip_addresses(request)
        eip_info = eip_response.body.to_map()
        eips.extend([
            {
                'AllocationId': eip['AllocationId'],
                'Name': eip.get('Name', ''),
                'InstanceId': eip.get('InstanceId', ''),
                'InstanceType': eip.get('InstanceType', ''),
                'IpAddress': eip['IpAddress']
            }
            for eip in eip_info['EipAddresses']['EipAddress']
        ])
        if len(eip_info['EipAddresses']['EipAddress']) < page_size:
            break
        page_number += 1
    return eips 

获取ECS实例信息

获取ECS实例信息是通过调用ECS产品的DescribeInstancesRequest实现的。这里同样使用了分页机制来获取所有ECS实例的信息,并将结果存储在一个字典中

from alibabacloud_ecs20140526.models import DescribeInstancesRequest

def get_ecs_info(ecs_client, region_id):
    ecs_instances = {}
    page_number = 1
    page_size = 50
    while True:
        request = DescribeInstancesRequest(
            region_id=region_id,
            page_number=page_number,
            page_size=page_size
        )
        ecs_response = ecs_client.describe_instances(request)
        ecs_info = ecs_response.body.to_map()
        ecs_instances.update({
            instance['InstanceId']: {
                'InstanceId': instance['InstanceId'],
                'Name': instance.get('InstanceName', ''),
                'VpcId': instance['VpcAttributes']['VpcId']
            }
            for instance in ecs_info['Instances']['Instance']
        })
        if len(ecs_info['Instances']['Instance']) < page_size:
            break
        page_number += 1
    return ecs_instances

获取VPC信息

通过调用VPC产品的DescribeVpcsRequest实现的。这段代码也是采用了分页机制来确保可以获取所有VPC的信息,并将其存储在一个字典中

from alibabacloud_vpc20160428.models import DescribeVpcsRequest

def get_vpc_info(vpc_client, region_id):
    vpcs = {}
    page_number = 1
    page_size = 50
    while True:
        request = DescribeVpcsRequest(
            region_id=region_id,
            page_number=page_number,
            page_size=page_size
        )
        vpc_response = vpc_client.describe_vpcs(request)
        vpc_info = vpc_response.body.to_map()
        vpcs.update({
            vpc['VpcId']: {
                'VpcId': vpc['VpcId'],
                'VpcName': vpc.get('VpcName', '')
            }
            for vpc in vpc_info['Vpcs']['Vpc']
        })
        if len(vpc_info['Vpcs']['Vpc']) < page_size:
            break
        page_number += 1
    return vpcs

获取NAT网关信息

通过调用VPC产品的DescribeNatGatewaysRequest实现的。这一部分也使用了分页机制来确保可以获取所有NAT网关的信息,并将结果存储在一个字典中

from alibabacloud_vpc20160428.models import DescribeNatGatewaysRequest

def get_nat_gateway_info(vpc_client, region_id):
    nat_gateways = {}
    page_number = 1
    page_size = 50
    while True:
        request = DescribeNatGatewaysRequest(
            region_id=region_id,
            page_number=page_number,
            page_size=page_size
        )
        nat_response = vpc_client.describe_nat_gateways(request)
        nat_info = nat_response.body.to_map()
        nat_gateways.update({
            nat['NatGatewayId']: {
                'VpcId': nat['VpcId'],
                'VpcName': nat.get('VpcName', '')
            }
            for nat in nat_info['NatGateways']['NatGateway']
        })
        if len(nat_info['NatGateways']['NatGateway']) < page_size:
            break
        page_number += 1
    return nat_gateways

整合信息并输出

获取所有可用的地域,然后针对每一个地域初始化VPC和ECS客户端,获取EIP信息、ECS实例信息、VPC信息以及NAT网关信息。最后,结合这些信息输出,并将数据保存为Excel文件

import pandas as pd
from datetime import datetime

def main():
    all_regions = get_all_regions()
    data = []

    for region_id in all_regions:
        vpc_client, ecs_client = init_client(region_id)

        eips = get_eip_info(vpc_client, region_id)
        ecs_instances = get_ecs_info(ecs_client, region_id)
        vpcs = get_vpc_info(vpc_client, region_id)
        nat_gateways = get_nat_gateway_info(vpc_client, region_id)

        # 结合信息并输出
        print(f"Region: {region_id}")
        print("序号 实例ID/名称 IP地址 绑定实例类型/ID 专有网络")
        for idx, eip in enumerate(eips, start=1):
            instance_id = eip['InstanceId']
            instance_type = eip['InstanceType']
            vpc_id = ''
            vpc_name = ''

            if instance_type == 'EcsInstance':
                vpc_id = ecs_instances.get(instance_id, {}).get('VpcId', '')
                vpc_name = vpcs.get(vpc_id, {}).get('VpcName', '')
            elif instance_type == 'Nat':
                vpc_id = nat_gateways.get(instance_id, {}).get('VpcId', '')
                vpc_name = vpcs.get(vpc_id, {}).get('VpcName', '')

            print(f"{idx} {eip['Name'] or eip['AllocationId']} {eip['IpAddress']} {instance_type}/{instance_id} {vpc_id} {vpc_name}")
            data.append({
                "Region": region_id,
                "序号": idx,
                "实例ID/名称": eip['Name'] or eip['AllocationId'],
                "IP地址": eip['IpAddress'],
                "绑定实例类型/ID": f"{instance_type}/{instance_id}",
                "专有网络": f"{vpc_id} {vpc_name}"
            })

    # 保存到Excel文件
    df = pd.DataFrame(data)
    timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
    filename = f"/data/tmp/global_resource_info_{timestamp}.xlsx"
    df.to_excel(filename, index=False)
    print(f"数据已保存到 {filename}")
上一篇
下一篇