• horizon源码解析(资源接口调用)


    openstack的horizon是基于django框架开发,入口在代码库中/horizon/openstack_dashboard,了解django的会觉得该文件夹下文件比较熟悉。

    urls路由入口:

    # /horizon/openstack_dashboard/urls.py
    from openstack_dashboard.api import rest
    urlpatterns = [
        re_path(r'^$', views.splash, name='splash'),
        re_path(r'^api/', include(rest.urls)),
        re_path(r'^header/', views.ExtensibleHeaderView.as_view()),
        re_path(r'', horizon.base._wrapped_include(horizon.urls)),
    ]
    

    这里主要看api的路径,nova、cinder等资源的操作都是通过api路径来进行操作的,跟着import的路径查看rest下的urls文件。

    from django.urls import re_path
    urlpatterns = []
    # to register the URLs for your API endpoints, decorate the view class with
    # @register below, and the import the endpoint module in the
    # rest_api/__init__.py module
    def register(view):
        """Register API views to respond to a regex pattern.
        ``url_regex`` on a wrapped view class is used as the regex pattern.
        The view should be a standard Django class-based view implementing an
        as_view() method. The url_regex attribute of the view should be a standard
        Django URL regex pattern.
        """
        p = re_path(view.url_regex, view.as_view())
        urlpatterns.append(p)
        return view
    

    这里的register是一个路由注册器,这种写法可以让你在新增路由或者修改的时候,不需要修改urls文件,通过修改视图类中的url_regex即可完成。

    接下来查看一下nova的视图文件:

    # /horizon/openstack_dashboard/api/rest/nova.py
    # 普通django视图类写法,使用register装饰器来注册路由,使用regex_urls值来指定路由
    @urls.register
    class Volumes(generic.View):
        """API over all server volumes."""
        url_regex = r'nova/servers/(?P<server_id>[^/]+)/volumes/$'
        
        @rest_utils.ajax()
        def get(self, request, server_id):
            """Get a list of server volumes.
    
            The listing result is an object with property "items". Each item is
            a volume.
    
            Example GET:
            http://localhost/api/nova/servers/abcd/volumes/
            """
            volumes = api.nova.instance_volumes_list(request, server_id)
            return {'items': [s.to_dict() for s in volumes]}
    

    这个的register装饰器是用来注册路由,url_regex为视图指定的url路径。ajax的装饰器用来检测认证与参数格式,同时在服务出错时,处理异常情况。

    入口结构图:

    如果是需要修改已有模块入口的话,在相应的文件中新增视图或者修改视图。如果是需要添加其它模块的话,新增新的模块视图py文件,并在init文件中import(注册)。

    注意:新增路由的话,建议按照-模块名/资源名/资源id的格式来设计url,尽量与openstack设计风格保存一致。

    openstack源码十分规范,这里只说明一个的调用路径,其它的操作基本都是一样的。如上面nova视图文件中,获取虚拟机volume信息的接口,调用instance_volumes_list,我们跟上这个函数。

    # /horizon/openstack_dashboard/api/nova.py
    # rest文件夹中,视图中的调用,多在api文件夹下
    @profiler.trace
    def instance_volumes_list(request, instance_id):
        volumes = _nova.novaclient(request).volumes.get_server_volumes(instance_id)
    
        for volume in volumes:
            volume_data = cinder.cinderclient(request).volumes.get(volume.id)
            volume.name = cinder.Volume(volume_data).name
    
        return volumes
    

    trace装饰器:

    if not horizon_settings.get_dict_config('OPENSTACK_PROFILER', 'enabled'):
        def trace(function):
            return function
    else:
        def trace(function):
            func_name = function.__module__ + '.' + function.__name__
            decorator = profiler.trace(func_name)
            return decorator(function)
    

    这个装饰器有一点可以了解下,OPENSTACK_PROFILER这个参数。openstack在ocata版本引入的这个参数,启用这个参数之后可以在面板上方便的看到api调用情况。

    img

    client声明:

    @memoized.memoized
    def cached_novaclient(request, version=None):
        (
            username,
            token_id,
            project_id,
            project_domain_id,
            nova_url,
            auth_url
        ) = get_auth_params_from_request(request)
        if version is None:
            version = VERSIONS.get_active_version()['version']
        c = nova_client.Client(version,
                               username,
                               token_id,
                               project_id=project_id,
                               project_domain_id=project_domain_id,
                               auth_url=auth_url,
                               insecure=INSECURE,
                               cacert=CACERT,
                               http_log_debug=settings.DEBUG,
                               auth_token=token_id,
                               endpoint_override=nova_url)
        return c
    

    horizon调用其它服务,都是通过相应的client来进行调用的。horizon这块的调用就这么几层。最终资源的处理都是放在了相应的服务中,如虚拟机资源的处理在nova源码中,镜像资源的处理在glance源码中。

  • 相关阅读:
    opentsdb安装部署
    python发送邮件(html)例子
    python查库写库例子
    获取rds的cpu和内存使用情况
    数据库损坏的情况下如何获取到dbid
    grafana安装升级部署
    Specified key was too long
    mysql动态执行sql批量删除数据
    kafka删除topics
    cratedb导入json文件
  • 原文地址:https://www.cnblogs.com/52why/p/16352430.html
Copyright © 2020-2023  润新知