一个简单的插件不需要写一行代码就可以实现,按照下述步骤:

1)准备一个可以访问的互联网或者局域网Web地址,如:http://www.google.com

2)编写一个XML格式的配置文件,命名为scriptConfig.xml,内容如下:

<scriptConfiguration version="1.0">
    <key>com.google.search</key>
    <description>Google Search Web Page</description>
    <name>googlesearch</name>
    <vendor>Google</vendor>
    <extension parent="HomeView.Applications">
        <title locale="en">Google Search</title>
        <url display="window">http://www.google.com</url>
        <icon>http://www.google.com/p_w_picpaths/icons/product/search-32.gif</icon>
    </extension>
</scriptConfiguration>

选择一台安装了VMware vCenter的主机,在VMware vCenter安装目录的子目录..\VMware\Infrastructure\tomcat\webapps下再创建一个目录,命名为google-ui,然后把scriptConfig.xml放到这个目录下。

3)注册插件。假设刚才选择的那个VMware vCenter主机的IP地址为192.168.0.100,那么在浏览器中输入地址:https://192.168.0.100/mob,用VMware vCenter的管理员帐户和密码登录。依次点击页面上“content”--“ExtensionManager”--“RegisterExtension”,把“Value”里面的内容清空,然后将下面的内容拷贝进去,点击“Invoke Method”即完成注册。用VMware Client重新登录VMware vCenter,打开窗口“主页”,在“解决方案和应用程序”下就能看到“Google Search”图标了,点击图标,就能看到显示成Google主页的插件。

<extension>
    <description>
        <label>com.google.search</label>
        <summary>google search web page</summary>
    </description>
    <key>com.google.search</key>
    <version>1.0</version>
    <subjectName>/O=VMware/OU=CDE/CN=VI Client plugin</subjectName>
    <server>
        <url>https://*:8443/google-ui/scriptConfig.xml</url>
        <description>
            <label>com.google.search</label>
            <summary>google search web page</summary>
        </description>
        <company>Google</company>
        <type>com.vmware.vim.viClientScripts</type>
        <adminEmail>administrator@gmail.com</adminEmail>
    </server>
    <client>
        <version>1.0</version>
        <description>
            <label>com.google.search</label>
            <summary>google search web page</summary>
        </description>
        <company>Google</company>
        <type>com.vmware.vim.viClientScripts</type>
        <url>https://*:8443/google-ui/scriptConfig.xml</url>
    </client>
    <lastHeartbeatTime>2011-03-11T12:59:26.234375Z</lastHeartbeatTime>
</extension>

当然,如果做一个稍微复杂的插件,就得考虑很多问题了。

1. 插件程序的拓扑

plugin

VMware Client登录VMware vCenter,VMware vCenter根据插件的注册信息,读取插件的配置文件,将插件的URL地址返回给VMware Client,VMware Client将插件的Web页显示在界面上。

2. 插件程序的开发

2.1. 插件程序的界面:插件是一个Web程序,可以用ASP.Net,JSP,CGI或者PHP等语言进行开发,但插件的界面风格必须和VMware Client保持一致,可以参考文献http://www.vmware.com/support/developer/vc-sdk/vcplugin/vSphereClient_plugin_ui_guidelines.pdf,了解界面的制作要求。

2.2. 插件程序的参数:插件在VMware Client中显示,VMware Client在调用插件主页时,会在URL地址里面传递一些重要参数给插件。其中moref指明插件的属主虚拟机对象;sessionid指明VMware Client的登录信息;local指明VMware Client使用的多国语言;serviceurl指明VMware vCenter的IP地址。

2.3. 插件程序的通信:插件是独立的Web程序,它的运行与VMware vCenter没有任何关系,所以为了获取VMware vCenter的虚拟机对象信息,就必须与之通信。通信使用的开发包是VMware vSphere Web Services SDK。开发包中有完整的示例,在学习了这些示例后,读者就可以利用上述插件程序的参数开发自己的Web应用了。开发包下载地址:http://www.vmware.com/support/developer/vc-sdk/

3. 插件程序的部署

插件既然是Web程序,就必须部署在Web Server上,读者可以自己架设IIS或者Apache服务器。如果嫌繁琐的话,可以直接利用VMware vCenter已经安装好的Web服务,如上面2)所说,将Web文件置于tomcat\webapps目录下面。部署好以后,可以通过浏览器测试一下地址是否正确。

4. 插件程序的配置文件

配置文件有两个重要参数,第一是extension的parent属性,它指示了插件是出现在什么位置的,如VMware Client的主页,还是菜单,工具栏,或者是选项卡上。第二是extension的url子项,它指示了插件的Web页地址。配置文件和插件程序一样,要通过URL地址访问,因此也必须部署在Web Server上,部署方式可以参考插件程序的部署。

5. 插件程序的注册

插件程序的注册途径有很多,比如上面所说的直接在浏览器上操作,也可以使用perl或者powershell脚本注册,还可以编写java或者C#程序进行注册。java代码注册可以参考文献http://www.vmware.com/support/developer/vc-sdk/vcplugin/vSphere_Plugin_4_1_Technote.pdf,读者可以参考开发包的示例,将java语言的注册代码改成C#语言的注册代码。本人写的注册代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Net;
using System.Web.Services.Protocols;
using System.Runtime.Serialization.Formatters.Binary;
using Vim25Api;
using AppUtil;

namespace RegMyPlugin
{
    class RegMyPlugin
    {
        private ManagedObjectReference _svcRef;
        private VimService _service;
        private ServiceContent _sic;
        private String companyStr = "Google";
        private String descStr = "Google Search Web Page";
        private String keyStr = "com.google.search";
        private String ext_url = "https://*:8443/google-ui/scriptConfig.xml";
        private String adminEmail = "administrator@gmail.com";
        private String versionStr = "1.0";

        public RegMyPlugin()
        {
            System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();
        }

        private void createServiceRef()
        {
            _svcRef = new ManagedObjectReference();
            _svcRef.type = "ServiceInstance";
            _svcRef.Value = "ServiceInstance";
        }

        private void connLoginReg(String hostName, String userName, String password)
        {
            String url = "https://" + hostName + "/sdk/vim";
            Description description = new Description();
            description.label = keyStr;
            description.summary = descStr;

            ExtensionServerInfo esi = new ExtensionServerInfo();
            esi.url = ext_url;
            esi.description = description;
            esi.company = companyStr;
            esi.type = "com.vmware.vim.viClientScripts";
            esi.adminEmail = new String[]{adminEmail};

            ExtensionClientInfo eci = new ExtensionClientInfo();
            eci.version = versionStr;
            eci.description = description;
            eci.company = companyStr;
            eci.type = "com.vmware.vim.viClientScripts";
            eci.url = ext_url;

            Extension ext= new Extension();
            ext.description = description;
            ext.key = keyStr;
            ext.version = versionStr;
            ext.subjectName = "/O=VMware/OU=CDE/CN=VI Client plugin";
            ext.server = new ExtensionServerInfo[]{esi};
            ext.client = new ExtensionClientInfo[]{eci};
            ext.lastHeartbeatTime = new DateTime(2011, 3, 11, 18, 7, 58);

            createServiceRef();

            _service = new VimService();
            _service.Url = url;
            _service.Timeout = 600000;
            _service.CookieContainer = new System.Net.CookieContainer();

            _sic = _service.RetrieveServiceContent(_svcRef);
            if (_sic.sessionManager != null)
            {
                _service.Login(_sic.sessionManager, userName, password, null);
                ManagedObjectReference extMgrMof = _sic.extensionManager;
                _service.RegisterExtension(extMgrMof, ext);
            }
        }

        static void Main(string[] args)
        {
            RegMyPlugin obj = new RegMyPlugin();
            String serverName = args[0];
            String userName = args[1];
            String password = args[2];
            obj.connLoginReg(serverName, userName, password);
        }
    }
}