如何创建一个zenpack(翻译)
?
如何创建一个zenpack 来添加新属性来扩展device
?
这篇文章你能获取到什么信息
这篇文章解释了如果创建一个zenpack来扩展device 增加 一个componet。如何增加一个新的snmp oid 到zenoss中,如何在gui上看到新的component(其实gui的部分坐着没写完)。
?
一个新的zenpack会包括:
1)一个device的子类
2)一个DeviceComponent的子类(里面包括了新的字段)
3)一个modeler 来获取新的oid 提供给 DeviceComponent
4)一个zope 模板来生成 试图展现在前端页面上(zeoss3.0 使用javascript来写了)
?
背景介绍
?
我已经阅读了zenoss的开发者文档和admin文档,但是任何地方都没发现一段描述创建一个zenpack完整的流程的章节。我搜索了网上能找到的代码,但是没有一个zenpack中的modeler会生成一些新的属性到device里。因为网上能找到的发布的zenpack里都没有扩展device和生成一个modeler。我在zenoos的论坛上找到了一篇名为《 Custom ZenPack Rough Guide》的帖子描述的内容正是我想要的,但是这个帖子唯一的问题是作者仅仅建议修改变量名,类名,和oid。这篇文章的另个问题是它正对的是老版本的zenpack,所以一些类名,包名,必须要修改才能在当前的系统中运行
?
Zenpack的目录结构
Zenpacks 必须有3个python包名来组成,用“.”来分开(例如ZenPacks.test.ZPool) 第一个包名一般都是Zenpack。文件之后会自动生成。
?
?
对于一个名叫Zenpacks.test.ZPool的zenpack来说目录结构一般为
<Zenoss home>/zenoss/ZenPacks/
?? ?ZenPacks.test.ZPool/ ?<Zenpack root directory>
?? ? ? ?ZenPacks.test.ZPool.egg-info
?? ? ? ?ZenPacks ? ? ? ? ? ? ?<The following directories will reflect the Zenpack name as python packages>
?? ? ? ? ? ?__init__.py
?? ? ? ? ? ?test
?? ? ? ? ? ? ? ?__init__.py
?? ? ? ? ? ? ? ?ZPool ? ? <任何model对象都应该放在此目录下>
?? ? ? ? ? ? ? ? ? ?__init__.py
?? ? ? ? ? ? ? ? ? ?daemons
?? ? ? ? ? ? ? ? ? ?datasources
?? ? ? ? ? ? ? ? ? ?lib
?? ? ? ? ? ? ? ? ? ?migrate
?? ? ? ? ? ? ? ? ? ?modeler ? ? ? ? ?<存放modeler module 通过oid来收集一些snmp信息>
?? ? ? ? ? ? ? ? ? ? ? ?__init__.py
?? ? ? ? ? ? ? ? ? ? ? ?plugins
?? ? ? ? ? ? ? ? ? ? ? ? ? ?__init__.py
?? ? ? ? ? ? ? ? ? ? ? ? ? ?ZPoolDeviceDetailsModeler.py ? <modeler module(collector)>
?? ? ? ? ? ? ? ? ? ?objects
?? ? ? ? ? ? ? ? ? ?reports
?? ? ? ? ? ? ? ? ? ?skins ? ? ? ? ? <存放视图模板,用在GUI上展示数据>
?? ? ? ? ? ? ? ? ? ? ? ?__init__.py
?? ? ? ? ? ? ? ? ? ? ? ?ZenPacks.test.ZPool ?<name of Zenpack>
?? ? ? ? ? ? ? ? ? ? ? ? ? ?ZPoolDeviceDetailTemplate.pt
?
Model objects
?
model object 应该被存放在 zenpack名最后一个点后面那个名字的文件夹中。(Zenpack.test.ZPool的话就是在ZPool文件夹)
增加一个component到device中,我们需要做如下事:
1)创建一个继承device的对象(它增加一个新的关系到device中),在这个例子中,我命名它为ZPoolDevice。
2)创建一个对象 继承DeviceComponent和ManagedEntity (里面同时定义了一个新的关系链接到ZPoolDevice),命名为ZPoolComponet。
?
ZPoolDevice 内容
?此时在zenpack的日志里可以看到‘Health for ZPool %s Collected health is %s’,的内容,但是还不能通过GUI看到。(因为作者没有完成GUI部分的代码)
?
其实我觉得翻的还是比较烂的,大家看的不舒服可以看原文。
原文出处:http://georgefakhri.wordpress.com/2009/07/15/how-to-create-a-zenpack/
?
我跟作者开始写这篇文章时的感受一样,在zenoss的开发文档中没有一段比较简单的讲述一个最基本的zenpack的开发流程,它将很多功能拆分开来将, 而且代码也没很详细的解释,大多数都是贴出其中的一段。最后在作者的这篇文章的评论中发现了一份相对详细的zenpack的文档地址:http://community.zenoss.org/docs/DOC-10268,我看完之后我自己对zenpack大致上有了粗略的一些了解。
?
zenpack最基本的开发如上所说的就4部分
1)device文件,用来创建一个对象,链接到device,此例中是ZPoolDevice。
2)component文件,新device的新属性在此文件中定义,GUI中页面的下拉选项也在次定于,还有一些函数用来当调用数据库中对象属性时初始化用(我自己还没找到modeler中获取到的数据存在哪里了,很苦恼)见ZPoolComponent.py
3)modeler 文件及时一个collector,用过snmp来获取数据,用process()方法来解析,处理,存储数据,见ZPoolDeviceDetailModeler.py
4)最后需要一个文件来将获取的数据展示到页面上,在zenoss3之前是用过skin中的。pt文件,是html写的,zenoss3开始通过使用javascript来写。
?
我自己现在将作者这篇没写完的部分写好了,但是一直界面上看不到,很郁闷。国内,即使是国外zenpack的资料实在太少,官方文档也比较烂。。。没啥多说的。很郁闷。
by:pakoo
email:zealzpc@gmial.com
已经写完GUI部分顺利调试通过,过几天写份完整的开发介绍。
?
先附上GUI代码
info.py
(function(){var ZC = Ext.ns('Zenoss.component');function render_link(ob) { if (ob && ob.uid) { return Zenoss.render.link(ob.uid); } else { return ob; }}ZC.ZPoolInterfacePanel = Ext.extend(ZC.ComponentGridPanel, { constructor: function(config) { config = Ext.applyIf(config||{}, { componentType: 'ZPool', fields: [ {name: 'zPoolName'}, {name: 'health'}, {name: 'uid'}, {name: 'name'}, {name: 'severity'}, {name: 'status'}, {name: 'hasMonitor'}, {name: 'monitor'}, ], columns: [{ id: 'severity', dataIndex: 'severity', header: _t('Events'), renderer: Zenoss.render.severity, width: 60 },{ id: 'zPoolName', dataIndex: 'zPoolName', header: _t('zPoolName'), sortable: true },{ id: 'health', dataIndex: 'health', header: _t('health'), sortable: true, },{ id: 'name', dataIndex: 'name', header: _t('Name'), width: 120, sortable: true },{id: 'monitored',dataIndex: 'monitored',header: _t('Monitored'),width: 60}] }); ZC.ZPoolInterfacePanel.superclass.constructor.call(this, config); }});Ext.reg('ZPoolComponent', ZC.ZPoolInterfacePanel);ZC.registerName('ZPoolComponent', _t('ZPool Component'), _t('ZPool Component'));})();?