实现对network/subnet/vm的快速添加和删除
- 首先电脑上安装python 2.7和openstacksdk这个package
- 目录下有两个文件,一个是auto.py,一个是openstack_util.py
- openstack_util.py,使用时注意project_id的赋值
# coding: utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
import os
import re
import datetime
import openstack
__all__ = ['get_connection', 'get_network', 'get_network_list', 'get_subnet', 'get_subnet_list', 'get_flavor',
'get_image', 'get_image_list', 'delete_network', 'create_network', 'create_subnet',
'create_keypair', 'create_vm', 'delete_vm', 'delete_vm_with_regex', 'delete_network_with_regex']
default_auth = {
"project_id": "afa9ef6caea84c72b0a7a07022ae6d80",
"user_domain_id": "default",
'username': "admin",
'password': "yunshan3302",
"auth_url": "http://10.25.71.90:5000/v3"
}
class GetObjFail(Exception):
pass
def singleton(cls):
"""
@summary: 将初始化好的实例放置到instances中, 以后再次初始化时,直接提取初始化好的实例
"""
instances = {}
def _singleton(auth, *args, **kw):
# 如果auth参数有变更,则重新初始化,实现的伪单例模式
if cls not in instances:
instances[cls] = cls(auth, *args, **kw)
elif auth != instances[cls].auth:
instances[cls] = cls(auth, *args, **kw)
# print 'instances: ', instances
return instances[cls]
return _singleton
@singleton
class Connection(object):
def __init__(self, auth=None, auth_expire=None):
"""
:param auth: 认证参数。格式如下:
auth = {
"project_id": "59840d75b6c046b1885cb58dab9279ea",
"user_domain_id": "default",
'username': "admin",
'password': "yunshan3302",
"auth_url": "http://10.25.178.10:5000/v3"
}
:param auth_expire: token超时时间,默认为1h
"""
self.auth = auth if auth is not None else default_auth
self.auth_type = 'password'
self.conn = None
self._init_conn_time = None
self._get_conn_time = None
self.auth_expire = auth_expire if auth_expire is not None else \
datetime.timedelta(hours=1) # expire time: 1h
self._init_conn()
def _init_conn(self):
self.conn = openstack.connect(auth=self.auth, auth_type=self.auth_type)
self._init_conn_time = datetime.datetime.now()
def _time_expired(self):
return self._get_conn_time - self._init_conn_time >= self.auth_expire
def get_connection(self):
self._get_conn_time = datetime.datetime.now()
if self.conn is None or self._time_expired():
self.conn = openstack.connect(auth=self.auth, auth_type=self.auth_type)
self._init_conn_time = datetime.datetime.now()
return self.conn
def get_connection(auth=default_auth):
# type: () -> object
return Connection(auth=auth).get_connection()
def get_image(image_id, connection=None, ignore_missing=False):
"""
@summary: 根据image_name获取image对象(openstack.compute.v2.image.ImageDetail)
:param image_id: str, image uuid
:param connection: Connection object
:param ignore_missing: 如果未找到,是否raise fail,默认raise
:return: image对象(openstack.compute.v2.image.ImageDetail) or raise get image failed
"""
conn = connection if connection is not None else get_connection()
for image in conn.compute.images():
if image.id == image_id:
return image
if not ignore_missing:
raise GetObjFail('get image <{}> failed!'.format(image_id))
def get_image_list(image_name, connection=None):
"""
@summary: 根据image_name获取image对象列表(image名称可以重复)
:param image_name: str, image名称
:param connection: Connection object
:return: image对象列表
"""
conn = connection if connection is not None else get_connection()
image_lst = []
for image in conn.compute.images():
if image.name == image_name:
image_lst.append(image)
return image_lst
def get_flavor(flavor_name, connection=None, ignore_missing=False):
"""
@summary: 根据flavor_name获取flavor对象
:param flavor_name: str, flavor名称
:param connection: Connection object
:param ignore_missing: 如果未找到,是否raise fail,默认raise
:return: flavor对象(openstack.compute.v2.flavor.FlavorDetail)
"""
conn = connection if connection is not None else get_connection()
for flavor in conn.compute.flavors():
if flavor.name == flavor_name:
return flavor
if not ignore_missing:
raise GetObjFail('get flavor <{}> failed!'.format(flavor_name))
def get_network_list(network_name, connection=None):
"""
@summary: 根据network_name获取network对象的列表(network名称可以重复)
:param network_name: str, network名称
:param connection: Connection object
:return: network对象列表
"""
conn = connection if connection is not None else get_connection()
net_lst = []
for network in conn.network.networks():
if network.name == network_name:
net_lst.append(network)
return net_lst
def get_network(network_id, connection=None, ignore_missing=False):
"""
@summary: 根据network_id获取network对象
:param network_id: str, network uuid
:param connection: Connection object
:param ignore_missing: 如果未找到,是否raise fail,默认raise
:return: network对象
"""
conn = connection if connection is not None else get_connection()
for network in conn.network.networks():
if network.id == network_id:
return network
if not ignore_missing:
raise GetObjFail('get network <{}> failed!'.format(network_id))
def get_subnet_list(subnet_name, connection=None):
"""
@summary: 根据subnet_name获取subnet对象列表(subnet名称可以重复)
:param subnet_name: str, subnet名称
:param connection: Connection object
:return: subnet对象列表
"""
conn = connection if connection is not None else get_connection()
subnet_lst = []
for subnet in conn.network.subnets():
if subnet.name == subnet_name:
subnet_lst.append(subnet)
return subnet_lst
def get_subnet(subnet_id, connection=None, ignore_missing=False):
"""
@summary: 根据subnet_id获取subnet对象
:param subnet_id: str, subnet uuid
:param connection: Connection object
:param ignore_missing: 如果未找到,是否raise fail,默认raise
:return: subnet对象
"""
conn = connection if connection is not None else get_connection()
for subnet in conn.network.subnets():
if subnet.id == subnet_id:
return subnet
if not ignore_missing:
raise GetObjFail('get subnet <{}> failed!'.format(subnet_id))
def create_network(net_name, connection=None, **kwargs):
"""
@summary: 创建租户网络
:param net_name: 网络名称
:param connection: Connection object
:param kwargs: 支持参数及默认值如下:
shared=False
admin_state_up=True
external=False
provider=None
project_id=None
availability_zone_hints=None
port_security_enabled=None
mtu_size=None
:return: network object
"""
conn = connection if connection is not None else get_connection()
return conn.network.create_network(name=net_name, **kwargs)
def create_subnet(network_id, subnet_name, cidr,
ip_version=4, enable_dhcp=False, connection=None, **kwargs):
"""
@summary: 为network创建子网,返回subnet对象
:param network_id: network uuid
:param subnet_name: str, 子网名称
:param cidr: str, 格式:'10.8.8.0/24'
:param ip_version: 默认为4
:param enable_dhcp: 是否开启dhcp,默认关闭
:param connection: Connection object (openstack.connect.Connection)
:param kwargs: 格式及默认值如下:
tenant_id=None
allocation_pools=None
gateway_ip=None
disable_gateway_ip=False
dns_nameservers=None
host_routes=None
ipv6_ra_mode=None
ipv6_address_mode=None
prefixlen=None
use_default_subnetpool=False
:return: subnet object
"""
conn = connection if connection is not None else get_connection()
return conn.network.create_subnet(
network_id=network_id,
name=subnet_name,
cidr=cidr,
ip_version=ip_version,
enable_dhcp=enable_dhcp,
**kwargs
)
def delete_network(network_id, ignore_missing=False, connection=None):
conn = connection if connection is not None else get_connection()
# 如果是新创建的network,并创建了sunbet, 需要重新get该network对象,原有创建的network没有subnet
network = get_network(network_id, ignore_missing=ignore_missing)
# TODO 需要确认是否需要先清除port, 目前来看木有问题`o`
# 先删除subnet
for subnet_id in network.subnet_ids:
conn.network.delete_subnet(subnet_id, ignore_missing=ignore_missing)
# 再删除network
conn.network.delete_network(network.id, ignore_missing=ignore_missing)
def create_keypair(key_name, key_dir, keyfile, connection=None):
conn = connection if connection is not None else get_connection()
keypair = conn.compute.find_keypair(key_name)
if keypair:
# 如果key_name的keypair已经存在,删除keypair
conn.compute.delete_keypair(key_name)
keypair = conn.compute.create_keypair(name=key_name)
if not os.path.exists(key_dir):
os.mkdir(key_dir)
keyfile = os.path.join(key_dir, keyfile)
with open(keyfile, 'w') as f:
f.write("%s" % keypair.private_key)
# os.chmod()
return keypair, keyfile
def create_vm(vm_name, image_name, flavor_name, network_id,
connection=None, keypair=None, keyfile=None):
conn = connection if connection is not None else get_connection()
image = conn.compute.find_image(image_name)
flavor = conn.compute.find_flavor(flavor_name)
if keypair is not None and keyfile is not None:
vm = conn.compute.create_server(
name=vm_name, image_id=image.id, flavor_id=flavor.id,
networks=[{"uuid": network_id}], key_name=keypair.name, config_drive=True)
else:
vm = conn.compute.create_server(
name=vm_name, image_id=image.id, flavor_id=flavor.id,
networks=[{"uuid": network_id}], config_drive=True,
# max_count=5,
)
vm = conn.compute.wait_for_server(vm)
# print("ssh -i {key} root@{ip}".format(
# key=keyfile,
# ip=vm.access_ipv4))
return vm
def delete_vm(vm, connection=None):
conn = connection if connection is not None else get_connection()
conn.compute.delete_server(vm)
def delete_all_vms(connection=None):
conn = connection if connection is not None else get_connection()
for vm in conn.compute.servers():
conn.compute.delete_server(vm)
def delete_vm_with_regex(name_pattern, connection=None):
conn = connection if connection is not None else get_connection()
if isinstance(name_pattern, basestring):
name_pattern = re.compile(name_pattern)
for vm in conn.compute.servers():
if re.search(name_pattern, vm.name):
conn.compute.delete_server(vm)
def delete_network_with_regex(net_pattern, connection=None):
conn = connection if connection is not None else get_connection()
if isinstance(net_pattern, basestring):
net_pattern = re.compile(net_pattern)
for net in conn.network.networks():
if re.search(net_pattern, net.name):
for subnet_id in net.subnet_ids:
conn.network.delete_subnet(subnet_id, ignore_missing=False)
# 再删除network
conn.network.delete_network(net.id, ignore_missing=False)
if __name__ == '__main__':
import pdb
conn = get_connection()
pdb.set_trace()
- 用于操作的脚本,按需注释/去除注释,然后运行
#!/usr/bin/python
# coding: utf-8
from openstack_util import *
import time
net_num = 2
vm_per_net = 3
for net_id in range(1,net_num+1):
net = create_network('autonet'+str(net_id))
subnet = create_subnet(net.id, 'autosubnet'+str(net_id), '10.99.'+str(net_id)+'.0/24', ip_version=4, enable_dhcp=False, connection=None)
print net
print subnet
for vm_id in range(1,vm_per_net+1):
vm = create_vm('autovm'+"-"+str(net_id)+"-"+str(vm_id), 'cirros', 'tiny', str(net.id), connection=None, keypair=None, keyfile=None)
print vm
# delete_vm_with_regex(r'autovm-\d+-\d', connection=None)
# time.sleep(5)
# delete_network_with_regex(r'autonet\d+', connection=None)
网友评论