类:
class NovaApi(): def __init__(self): self.ip = controller_ip self.port = nova_port self.http_protocol = http_protocol self.endpoint = '{}://{}:{}'.format(self.http_protocol, self.ip, self.port) self.token = Keystone.token self.admin_token = Keystone.admin_token self.DIR_PATH = os.path.dirname(__file__) self.log = Logger('../Log/Nova.log', level='info').logger def listVms(self): url = '{}/v2.1/servers'.format(self.endpoint) base_header["X-Auth-Token"] = self.token r = requests.get(url=url, headers=base_header, verify=False) if r.status_code == 200: res = json.loads(r.content) server_list = res.get('servers') return server_list else: self.log.error('list vms request failed! {}-{}'.format(r.status_code, r.content)) return False @nova_new_header def addOneVmUseLocalDiskNet(self, name, imageRef, flavorRef, network_id, availability_zone="nova", diskConfig="AUTO", description=None, security_groups: list = [{"name": "default"}]): url = '{}/v2.1/servers'.format(self.endpoint) body = { "server": { "name": name, "imageRef": imageRef, "flavorRef": flavorRef, "availability_zone": availability_zone, "OS-DCF:diskConfig": diskConfig, "description": description, "security_groups": security_groups, "networks": [ { "uuid": network_id, } ] } } body = json.dumps(body) r = requests.post(url=url, data=body, headers=base_header, verify=False) if r.status_code == 202: res = json.loads(r.content) self.log.info('vm:{} create success!'.format(name)) vm_info = res.get('server') return vm_info else: self.log.error('create vm failed!-{}-{}'.format(r.content,r.status_code)) return False
这个类中方法都需要在请求的时候传递header,但是他们的header会有所区别,所以需要使用不同的装饰器进行解决,如上:@nova_new_header,会将self.token传递给装饰器中的base_header
装饰器:
def nova_new_header(func_or_cls): def wapper(self,*args, **kwargs): base_header["X-Auth-Token"] = self.token base_header["X-OpenStack-Nova-API-Version"] = '2.65' res = func_or_cls(self,*args, **kwargs) return res return wapper
这样就可以在装饰器中将__init__中的self.token传递给func_or_cls,并且同时定义了API的微版本号。