Cliff框架介绍

来源:互联网 发布:淘宝返现处罚 编辑:程序博客网 时间:2024/06/05 20:02


1 cliff简介

    Cliff(CommandLine Interface Formulation Framework),即命令行接口制定框架。可定义多级命令、输出格式以及其他一些扩展来创建命令行相关项目。Cliff框架中定义的主程序处理参数解析,并调用子命令来完成工作。

    Cliff借助Python的优势能够动态的装载代码,允许主程序中用到的子命令分布式的实现,并向用户提供统一的命令行界面,方便开发者组织源码。Neutron提供了命令行模式、交互式模式,正是基于cliff架构实现的。

cliff框架中包括了最基本的四类对象

1     theapplication

Cliff.app.App是cliff框架的主程序,负责参数解析、配置logging、设置I/O流等。

2      theCommandManager

cliff.commandmanager.CommandManager 用于加载子命令,默认是通过setuptools entry points机制实现。

3      theCommand

cliff.command.Command 可通过继承该类实现相应的子命令供主程序调用。

4      theInteractive Application

主程序调用cliff.interactive.InteractiveApp实例向用户提供command-shell模式,用户可输入多个命令。

cliff objects之间的关系

    Cliff.app.App类中,初始化函数包括定义self.commandmanager,它是cliff.commandmanager.CommandManager的实例,self.interactive-app-factory,它是cliff.interactive.InteractiveApp的实例。run()函数是主程序入口函数。

输出格式

   List命令提供的输出格式:csv, table, value, yaml, json, HTML,使用方法是在命令后面输入:-f 输出格式;Show命令提供的输出格式:table,shell, value, yaml, json, HTML,下面举例介绍各种格式的特点,HTML格式需要安装cliff-tablib,这里不做演示。

  Csv格式:

(.venv)$ cliffdemo files -f csv

"Name","Size"

"build",136

"cliffdemo.log",2690

"Makefile",5569

"source",408

 Table格式:

(.venv)$ cliffdemo files

+---------------+------+

|      Name     | Size |

+---------------+------+

| build         |  136 |

| cliffdemo.log | 2546 |

| Makefile      | 5569 |

| source        |  408 |

+---------------+------+

  Value格式

(.venv)$ cliffdemo files -f value

build 136

cliffdemo.log 2690

Makefile 5569

source 408

  Yaml格式:

(.venv)$ cliffdemo files -f yaml

- Name: dist

  Size: 4096

- Name: cliffdemo.egg-info

  Size: 4096

- Name: README.rst

  Size: 960

- Name: setup.py

  Size: 1807

  Json 格式:

(.venv)$ cliffdemo files -f json

[

  {

    "Name": "source",

    "Size": 4096

  },

  {

    "Name": "Makefile",

    "Size": 5569

  },

]

  Shell格式:

(.venv)$ cliffdemo file -f shell setup.py

name="setup.py"

size="5916"

uid="527"

gid="501"

modified_time="1335655655.0"

OpenStack与cliff的关系

   Openstack提供的命令行程序正是基于cliff框架编写。Neutron-client实现了用于调用Neutron APIs 命令行接口。Neutronclient的主程序NeutronShell类继承cliff.app.App类,初始化函数中定义了command-manager,interactive-app。对终端输入的neutron命令进行参数解析、配置logging并调用相关子命令来完成neutron命令操作。输入的命令是由sys.argv[1:]获取。

Neutronclient目录结构:

neutronclient

   ---common

   ---neutron

       --v2_0

       --client.py

---tests

---v2_0

---client.py

---i18n.py

---shell.py

---version.py

  

neutron-client中如何添加CLI命令

   通过添加neutronservice-create命令来介绍,当终端输入service-create命令时,要求输出service-create命令所有的参数,且参数可用。

 1、注册新的CLI命令

Neutron提供的命令行接口是定义在python-neutronclient/neutronclient/shell.py文件,以字典形式注册在COMMAND_V2中,因此需要在COMMAND_V2中注册新的命令:

COMMAND_V2 = {

    'net-list': network.ListNetwork,

    …

'service-create': network.CreateService,

}

 

Service-create具体实现是在network.py文件提供的CreateService类中实现。

2、设置service-create命令提供的参数

这部分设置是在类CreateService中实现。

import argparse  # 调用argparse模块用于参数解析,参数添加,参数行为设置等

 

from neutronclient.common import exceptions

from neutronclient.i18n import _

from neutronclient.neutron import v2_0 as neutronV20  # 该类提供了CreateCommand类

 

class CreateService(neutronV20.CreateCommand):

    """Create a service."""

 

    resource = 'service'     # neutron client向OpenStack API端对service资源进行操作

 

    def add_known_arguments(self, parser):         # 对service-create命令添加参数,并设置参数的行为

        parser.add_argument(

            '--admin-state-down',

            dest='admin_state', action='store_false',

            help=_('Set admin state up to false.'))

        parser.add_argument(

            '--admin_state_down',

            dest='admin_state', action='store_false',

            help=argparse.SUPPRESS)

        parser.add_argument(

            'name', metavar='NAME',

            help=_('Name of service to create.'))

        parser.add_argument(

            '--description',

            dest='description',

            help=_('Description of the service'))

        parser.add_argument(

            '--shared', dest='share',

            choices=['True', 'False'],

            default=argparse.SUPPRESS,

            help=_('Shared or not'))

        parser.add_argument(

            '--test', dest='test',

            action='store_const',

            const='value-to-const',

            help=_('Test for const value'))

        parser.add_argument(

            '--ips', dest='ips',

            nargs=2,

            default='a',

            help=_('Add multible arguments'))

        parser.add_argument(

            '-r', '--retries',

            metavar="NUM",

            dest='r',

            type=int,

            default=0,

            help=_("How many times the request to the Neutron server should "

                   "be retried if it fails."))

 

    def args2body(self, parsed_args):

        body = {'service': {

            'name': parsed_args.name,

            'admin_state_up': parsed_args.admin_state,

            'ips': parsed_args.ips,

            'description':parsed_args.description,

            'test': parsed_args.test,

            'shared': parsed_args.share,

            'r': parsed_args.r}, }

        neutronV20.update_dict(parsed_args, body['service'],

                               ['shared', 'tenant_id'])

        return body

  代码中向service-create命令添加了如下参数:

1 --admin-state-down/--admin_state_down,其action:store-false,表示其默认值为false,输入为true。

2  name,前面没有添加‘—’表示为必选参数,输入service-create命令时必须输入name。

3  --description,没有添加action,但默认action是type=str,表示该值是字符串形式。

4  --shared,带有choice选项,表示该值只可是choice中的一个值。

5  --test,action值为‘store-const’,表示test值在const中指定。

6  --ips,action值为‘nargs=2’,表示ips可选参数后面需加两个值。

7  -r,参数--retries,是-r参数的别名,区别是前面的短横线个数不同。其中type=int,表示其输入值是整形数值。

3、显示新添加的命令其参数值

根据neutron-client中代码执行走向,在CreateService类的父类CreateCommand中定义的get-data()函数中输出命令的返回结果。

class CreateCommand(NeutronCommand, show.ShowOne):

    """Create a resource for a given tenant.""

    def get_parser(self, prog_name):

       … …

    def get_data(self, parsed_args):

        self.log.debug('get_data(%s)' % parsed_args)

        _extra_values = parse_args_to_dict(self.values_specs)

        _merge_args(self, parsed_args, _extra_values,

                    self.values_specs)

        body = self.args2body(parsed_args)    # body中返回所创建的service下所有的参数及对应的值

        print("_extra_values")

        print(_extra_values)

        print("body:")

        print(body)

        return

        neutron_client = self.get_client()  # 设置neutron-client,调用OpenStack APIs

        neutron_client.format = parsed_args.request_format

        … …

   执行service-createabc  --retries 2 - -shared True ,或者执行service-create abc  -r 2 - -shared True,返回结果相同。

service-create abc --retries 2 --shared True

_extra_values

{}

body:

{'service': {'description': None, 'admin_state_up': True, 'ips': 'a, b', 'r': 2, 'test': None, 'shared': 'True', 'name': 'abc'}}

 

 参考资料

Cliff文档:http://docs.openstack.org/developer/cliff/

Cliff源码:https://github.com/dreamhost/cliff

Argparse模块:http://www.2cto.com/kf/201208/149418.html

                http://blog.itpub.net/26250550/viewspace-1281968/

http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=21633169&id=4387657

 

0 0
原创粉丝点击