基于boto的几个Elastic IP的用法

来源:互联网 发布:em算法 李航 编辑:程序博客网 时间:2024/05/16 05:14

原始的boto关于ElasticIP的api使用起来比较不友好,例如实例与EIP关联的时候,需要给出VPC里的EIP的allocation_id,而allocation_id要从eip的属性里找出来,disassociate eip的时候,需要提供association_id,这个id比较难找。而常规的思路是,不管是关联和解关联,只需要提供实例ID和EIP就行,因此我封装了几个函数来使EIP的使用变的稍微友好点。
(ElasticIP和PublicIP的区别,详见我的这篇文章http://imbusy.me/elastic_ip-and-public_ip.html)

1,将eip的allocation函数封装,返回IP和allocationIP的字典,供后面关联函数使用

import boto.ec2region = 'ap-southeast-1'def eip_allocation(domain='vpc'):    conn = boto.ec2.connect_to_region(region)    allocation = conn.allocate_address(domain='vpc', dry_run=False)    return {'public_ip':allocation.public_ip,            'allocation_id':allocation.allocation_id}

返回字典例如
{'public_ip':'54.169.xx.xx', 'allocation_id':'eipalloc-b2e3xxxx'}

2,原始的associate函数需要给出实例ID和EIP的allocation_id,那假如不是分配IP后立即使用,而是把已经存在的EIP与实例关联,这样就得通过EIP来解析出allocation_id,于是重新包装下,使其只需要实例ID和EIP即可,而eip_allocation函数正好二者都返回,随便选用。

def eip_association(instance_id,public_ip):    '''Notice: need InstanceID and PublicIP to make association'''    conn = boto.ec2.connect_to_region(region)    ##make sure input ip is valid EIP    try:        address = conn.get_all_addresses(addresses=[public_ip])    except boto.exception.EC2ResponseError:        print "Error: IP not found or not EIP"    else:        allocation_id = address[0].allocation_id    ## to call boto associate_address func    conn.associate_address(        instance_id=instance_id,        public_ip=None,        allocation_id=allocation_id,        network_interface_id=None,        private_ip_address=None,        allow_reassociation=False,        dry_run=False)

3,disassociate原始的函数也是需要association_id的,而正常思路是只需要提供EIP就可以将其与实例解除关联,于是重新包装了函数,只需要给出EIP就能解除关联

def eip_disassociation(public_ip):    conn = boto.ec2.connect_to_region(region)    '''Notice: use public_ip to get network_interface_id    and use network_interface_id to get association_id'''    ##make sure input ip is valid EIP    try:        address = conn.get_all_addresses(addresses=[public_ip])    except boto.exception.EC2ResponseError:        print "Error: IP not found or not EIP"    else:        association_id = address[0].association_id        #network_interface_id = address[0].network_interface_id        conn.disassociate_address(        public_ip=None,        association_id=association_id,        dry_run=False)

4,释放EIP,重新包装了下,使其不需要allocation_id,只需要给出EIP就能释放,并且会判断EIP是否被使用,只有没被使用的EIP才能被释放,当然,每个函数还有个判断输入的EIP是否为真实的EIP。

def eip_release(public_ip):    conn = boto.ec2.connect_to_region(region)    ##make sure input ip is valid EIP    try:        address = conn.get_all_addresses(addresses=[public_ip])    except boto.exception.EC2ResponseError:        print "Error: IP not found or not EIP"    else:        association_id = address[0].association_id        allocation_id = address[0].allocation_id    ## only release EIP that not associated to any instance    if association_id == None:        conn.release_address(            public_ip=None,            allocation_id=allocation_id)    else:        print "IP %s is in use, cannot be released" % public_ip

5,重新构造了个函数,用户给实例快速更换EIP,适用于爬虫服务器,因为他的IP经常被封掉。另外提一句,如果实例创建之初自动分配过Public IP的话,关联EIP之后,PublicIP也会变成与ElasticIP一样(被覆盖),等解除EIP关联之后,PublicIP才会显露,但此时会重新分配,因此PublicIP会变。

def eip_change(instance_id):    conn = boto.ec2.connect_to_region(region)    reservations = conn.get_all_reservations([instance_id])    instances = reservations[0].instances    inst = instances[0]    old_public_ip = inst.ip_address    ##make sure the public ip is valid EIP    try:        address = conn.get_all_addresses(addresses=[old_public_ip])    except boto.exception.EC2ResponseError:        print "Error: Old public IP not found or not EIP"    else:        eip_disassociation(old_public_ip)        eip_release(old_public_ip)    ## add new IP     allocation = eip_allocation()    public_ip = allocation['public_ip']    eip_association(instance_id,public_ip)

6,下面是主函数里的调用示例

def main():    #usage demos    #eip_disassociation('54.xx.xx.xx')    #eip_association('i-xxxxxxxx','54.xx.xx.xx')    #eip_release('54.xx.xx.xx')    #eip_change('i-xxxxxxxx')if __name__ == '__main__':    main()
0 0
原创粉丝点击