classClient(object): """ Top-level object to access the OpenStack Compute API. Create an instance with your creds:: >>> client = Client(USERNAME, PASSWORD, PROJECT_ID, AUTH_URL) Then call methods on its managers:: >>> client.servers.list() ... >>> client.flavors.list() ... """
注释里讲了怎么使用 python 命令行调用 nova 的 client
client 里给流入的指令分了很多类,以 flavors 为例,看 nova flavor-list 这个命令的流程
deflist(self, detailed=True, is_public=True): """ Get a list of all flavors. :rtype: list of :class:`Flavor`. """ qparams = {} # is_public is ternary - None means give all flavors. # By default Nova assumes True and gives admins public flavors # and flavors from their own projects only. ifnot is_public: qparams['is_public'] = is_public query_string = "?%s" % urlutils.urlencode(qparams) if qparams else""
classManager(utils.HookableMixin): """ Managers interact with a particular type of API (servers, flavors, images, etc.) and provide CRUD operations for them. """ resource_class = None
def__init__(self, api): self.api = api
def_list(self, url, response_key, obj_class=None, body=None): if body: _resp, body = self.api.client.post(url, body=body) else: _resp, body = self.api.client.get(url)
if obj_class isNone: obj_class = self.resource_class
data = body[response_key] # NOTE(ja): keystone returns values as list as {'values': [ ... ]} # unlike other services which just return the list... ifisinstance(data, dict): try: data = data['values'] except KeyError: pass
with self.completion_cache('human_id', obj_class, mode="w"): with self.completion_cache('uuid', obj_class, mode="w"): return [obj_class(self, res, loaded=True) for res in data if res]
novaclient.v1_1.flavors.py 里 FlavorManager 的 resource_class = Flavor 即 class Flavor(base.Resource)
所以最后 obj_class 为 Flavor
调用 api 的过程:
1 2 3 4
if body: _resp, body = self.api.client.post(url, body=body) else: _resp, body = self.api.client.get(url)
通过 self.api 到了 nova 的 api 里 nova.api.openstack.compute.init.py
@wsgi.serializers(xml=MinimalFlavorsTemplate) defindex(self, req): """Return all flavors in brief.""" limited_flavors = self._get_flavors(req) return self._view_builder.index(req, limited_flavors)
它最后会返回一个存放 flavors 信息的字典,这些原始数据经过提取和加工,最后在终端被打印出来
nova.api.openstack.compute.views.flavors.py :
1 2 3 4 5 6 7 8 9 10 11 12 13
def_list_view(self, func, request, flavors): """Provide a view for a list of flavors.""" flavor_list = [func(request, flavor)["flavor"] for flavor in flavors] flavors_links = self._get_collection_links(request, flavors, self._collection_name, "flavorid") flavors_dict = dict(flavors=flavor_list)
if flavors_links: flavors_dict["flavors_links"] = flavors_links
@utils.arg('server', metavar='<server>', help='ID of server.') @utils.arg('displayname', metavar='<name>', help='Display name for backup.') @utils.arg('description', default=None, metavar='<description>', help='Description for backup.(Default None)') defdo_backup_instance(cs, args): """Make a quick backup for instance.""" cs.servers.backup_instance(args.server, args.displayname, args.description)
defbackup_instance(self, server, backup_name, backup_description): """ Backup a server instance quickly. :param server: The :class:`Server` (or its ID) to share onto. :param backup_name: Name of the backup image :param backup_description: The backup description """ body = {'name': backup_name, 'description': backup_description} response_key = "id" return self._create("/servers/%s/backup_instance" % base.getid(server), body, response_key, return_raw=True)