码迷,mamicode.com
首页 > 其他好文 > 详细

新增NOVA接口(一)

时间:2016-05-04 12:02:09      阅读:301      评论:0      收藏:0      [点我收藏+]

标签:

           基于openstack kilo版本中的Nova代码,新增根据特定项目中的特定用户对外提供计算资源:vcpu ,ram统计的接口。

           原始openstack中的计算资源统计颗粒度只到达项目这个层面。所以需要新增针对单个用户的统计接口。思路是通过nova内部接口遍历出当前用户所在的项目中的所有虚机条目,然后根据用户ID进行匹配,获取匹配虚机的flavor,然后从flavor中取得ram,vcpu的值进行累加。最后返回单个用户的统计值。

      除了要考虑涉及api外,还需要考虑命令行的实现。此文先记录nova的api扩展,命令行的实现在下一文记录。

      nova中的扩展api作为一种扩展资源存在于nova的代码框架中。所以在下述目录中添加新的资源:

     技术分享

      为此功能新建文件:技术分享

      此文件中定义了资源类和操作资源的控制类;

      对于资源类,是按照扩展资源框架,继承

extensions.ExtensionDescriptor
      nova-api服务初始化加载extension资源时会遍历contrib目录,根据目录下的文件名,映射到文件中和文件同名的类,注册资源。所以,此文件中定义的资源类就是:

    

class Server_use_statistics(extensions.ExtensionDescriptor):
    """Server use statitistics support.
       currently only consider cpu ram sum by a user
       in a project
    """

    在此类中定义get_resource方法:

  

def get_resources(self):
    resources = []

    res = extensions.ResourceExtension(‘os-server-statistics‘,
                                        ServersStatisticsController(self.ext_mgr),
                                        member_actions={‘defaults‘: ‘GET‘})
    resources.append(res)

    return resources

     调用extensions中的方法注册了访问此资源的url,和对应处理的controller对象,其对应的就是

ServersStatisticsController 类。
         使用extensions扩展的资源访问的url是:http://controller:8774/v2/{tenant-id}/os-server-statistics/{user-id}

     接下来就是具体的处理类:

ServersStatisticsController
     这个类继承wsgi.controller

    

class ServersStatisticsController(wsgi.Controller):

     由于需要调用内部函数获取instance list。nova的设计中,计算资源的实现在如下目录中:

    技术分享

     处理compute相关的内部操作。所有关于计算资源的操作都通过API类进行了归集管理。所以要使用compute相关的接口,需要有一个方法的动态加载:

    

class ServersStatisticsController(wsgi.Controller):

    def __init__(self,ext_mgr=None):
        self.compute_api = compute.API()
        self.ext_mgr = ext_mgr

     每一个ServersStatisticsController对象都会挂载compute的处理接口供其使用。

     接下来,实现show函数,用以获取资源统计:

    

def show(self, req, id):
    ‘‘‘
    :request url: /v2/{tenant_id}/os-server-statistics/{user_id}
    :param req: user_id:the user to caculate
    :param id: input the tenant_id which the user belong to
    :return:
    ‘‘‘
    ‘‘‘
    :param req:
    :param id:
    :return:
    ‘‘‘
    context = req.environ[‘nova.context‘]
    user_id = id
    search_opts = {
        ‘deleted‘:False,
        ‘project_id‘:context.project_id,
    }

    limit = 1000
    marker = None

    sort_keys = [‘created_at‘]
    sort_dirs = [‘desc‘]

    used_ram = 0
    used_vcpu = 0

    try:
        instance_list = self.compute_api.get_all(context,
                                                 search_opts=search_opts,
                                                 limit=limit,
                                                 marker=None,
                                                 want_objects=True,
                                                 sort_keys=sort_keys,
                                                 sort_dirs=sort_dirs)
    except exception.MarkerNotFound:
        msg = _(‘marker [%s] not found‘) % marker
        raise exc.HTTPBadRequest(explanation=msg)
    except exception.FlavorNotFound:
        LOG.debug("Flavor ‘%s‘ could not be found", search_opts[‘flavor‘])
        instance_list = objects.InstanceList()

    if instance_list:
        for instance in instance_list:
            if instance.get(‘user_id‘) == user_id:
                used_ram += instance.get(‘flavor‘).get(‘memory_mb‘)
                used_vcpu += instance.get(‘flavor‘).get(‘vcpus‘)


    result = {
        ‘user_usage‘:{
                    ‘used_vcpus‘ : used_vcpu,
                    ‘used_rams‘ : used_ram
        }
    }
    return result
         前半部分都是为调用真正的处理函数做参数准备。最后调用get_all函数获取当前用户所在的项目下的所有instance.其实,nova list的命令最后调用的处理函数也是get_all。get_all函数返回的是包含完整instance信息的list.

这其中也包括此instance所使用的flavor的展开信息。也就是说,只要从此函数取得了instance信息,就可以直接从此数据中取得flavor中的ram和cpu信息。然而,nova list中是没有这些展开信息的。原因是因为,nova 的api层处理函数:技术分享

      

def _get_servers(self, req, is_detail):
    """Returns a list of servers, based on any search options specified."""

       对get_all取得的instance_list最后是做了信息的过滤:

     

if is_detail:
    instance_list.fill_faults()
    response = self._view_builder.detail(req, instance_list)
else:
    response = self._view_builder.index(req, instance_list)

      滤掉了一些数据。这也导致了外界通过现有的获取instance的api是无法一次性得到flavor的数据的原因。其实在内部接口中,get_all返回的数据是十分详尽的。

     然后就是过滤信息,统计使用的资源,最后按JSON格式返回数据。

    eg:

    GET:http://controller:8774/v2/61d86e0499e94217819d87006a20de88/os-server-statistics/50519e0465b44cf2ac01fa07590211f3


    结果:

    

  1. {
  2.    "user_usage":
  3.    {
  4.        "used_vcpus": 3,
  5.        "used_rams": 1536
  6.    }
  7. }

   

新增NOVA接口(一)

标签:

原文地址:http://blog.csdn.net/klyhuntermax/article/details/51312244

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!