Tuesday, June 12, 2012

A Google Docs Bug

Google Docs seems to have a bug with adding a center tab-stop. It's hard to tell what version I am using since Google doesn't show that anywhere. But I have tried this both as a regular Gmail user and as a Google Apps user.

This seems to happen only when adding a center tab-stop when a marked block (in my case, several list items), with one of the lines marked having a previously added center tab-stop -- It did not happen when that center tab-stop was previously added, nor did it happen after that center tab-stop was removed before this action is repeated.

Here is how it happens:

  1. Add one center tab-stop in the first list item line;
  2. Mark the list items;
  3. Add a center tab-stop in the same spot (being at the same spot may or may not matter);
  4. Immediately, you get the Google Docs error pop-up message in the middle of the window and the red error bar on the top (see screen captures below).

I have been able to reproduce this error in both Firefox and Chrome.

The work around seems to be removing existing center tab-stops. But I guess if there are many of them, that could get annoying.

Saturday, May 12, 2012

Random Ranting on Cisco Prime LMS

Cisco Prime LMS is the company's LAN Management Solution software, re-branded from the CiscoWorks label. I am sure there are many reason for the re-branding for marketing reasons, but one of them, I believe, is that CiscoWorks has never worked very well.

Cisco has a decent reputation with its networking gears, with the company's long history in the industry. What surprises me is that, Cisco's software (which is running all those iron boxes) are of such low quality that it is almost shocking.

Case in point: Cisco Prime LMS, which is at version 4.2 as of this writing. LMS also has had a long history. I am not into all the details but from what I have learned from working with it: there are a few main modules that Cisco has acquired from other companies -- the Campus Manager (CM), the Resource Management Essentials (RME), Device Fault Manager (DFM), Internetwork Performance Monitor (IPM), CiscoView, and more recently the Health and Utilization Monitor (HUM) is added into the mix. Before version 4, those modules are clearly displayed in CiscoWorks portal as distinctively independent pieces with visible overlaps and confusing user interface layouts. For example, many of those modules do Reports. I as the user of LMS need to know exactly where to go to create what report.

Although things have not changed much under the hood, so to speak, LMS 4.x versions have done a better job in presenting a more unified user interface over those modules that still function pretty much the same way they used to. The main menu is now organized into functional activities: Monitor, Inventory, Configuration, Reports, Admin and Work Centers -- These are now the main UI menu components.

Judging from what I have heard from others, it is not my ignorance of the product alone that makes it so difficult to use. The software is at version 4.2 at this point, to expect it to not break down randomly should not be an unreachable goal. But that just seems to keep happening.

A minor case of quality problem: I want to run a script to export the user tracking data. Since that data is then fed to other scripts that I don't control, I need to use a custom layout for the export so that I don't break other people's scripts.

I created the layout in the Report Designer. When I tried to use the layout, I got an error message saying that ERROR UTCLI: Error loading preferences. custom-ut-export-layout is not a valid layout name for this user.

Since there seems to be no way to allow a custom layout designed by one user to be used by another -- at least I have not been able to find that if it does exist, I deleted the layout. Logged out of my session. Logged back in under the user account in my script. Re-designed the layout with the same name. Re-ran my script. I got the same error.

I logged back in as the script user, went to the Custom Layouts page. My layout was nowhere to be found.

I logged out. Logged back in as myself. No custom layout of that name, or in fact, no layout besides the three standard ones in the list.

Out of ideas, I restarted the LMS. Logged back in, still nothing.

Logged back in as the script user, created the custom layout with a different name. I made a copy of it just in case. I logged out then back in again. Nothing. Both copies of my layouts are gone.

To make sure that I didn't confuse LMS, I restarted it, then repeated my steps. Still the same result: No custom layout.

At this point, I seem to have lost the capability to create custom layout with no clue about what I did wrong to get into such a bind. Maybe because I reused the layout name between two users? If that was a bad thing to do, I certainly did not receive a warning from the software.

I should probably start to look for an open source alternative to LMS.

Friday, May 11, 2012

SNMP MIB Version Control

I work with Cisco devices a lot, especially in network management. So I naturally have to work with SNMP. Cisco does a pretty good job when it comes to publishing their MIBs. But often I find much inconsistencies in their MIB file distributed from different sources. From minor issues of file-naming differences (you may find the same MIB in files with .mib, .my or .txt extensions), to major changes inside the MIB without a version update. This is probably not a problem that happens in Cisco alone.

It occurred to me that these files are just text, so source code version control tools are perfect for managing them. Digging around a little bit on Google Code and github, I found out some one had already done it.

The SnmpMibs project on github is just what I was thinking about. I hope that the project gets more widely recognized. Especially, I think network device vendors should adopt this model in publishing their MIBs, that would make this whole world a slightly better place.

Monday, May 7, 2012

Cisco LMS: It Depends on What "IS" Is

One has to be a certain age to understand the meaning of the statement: It depends on what the meaning of the word IS is. But the other day, Cisco's LAN Management Solution software gave me a subtle reminder.

After setting up the Cisco Prime LMS 4.2 appliance, and struggling through issues like throwing up an null pointer exception (Ironically, Java claims having no pointer as an advantage over C.) when looking up User Tracking summary, we find out that it is not archiving device configurations from most of our devices.

In troubleshooting this, I see that all descriptions of the job failures are the same:
SSH: Failed to establish SSH connection to 111.222.33.44 - Cause: Authentication failed on device 3 times. TELNET: Failed to establish TELNET connection to 111.222.33.44 - Cause:  Connection refused.   PRIMARY-STARTUP config Fetch Operation failed for TFTP.
That could not have been all true! Because when I manually SSH from the appliance to the device, using the credentials setup for LMS, I had not problem. In fact, when I do a Reachability Status test in Device Center, SSHv2 shows success.

In Reachability Status I did notice that SNMPv2c Write shows failed, which I did not dig into in the beginning thinking there may be an issue with an access list not getting updated to allow SNMP write traffic through. When I did credential test on a selected device, SNMP write succeeded, which initially lead me to think SNMP was not an issue. But then I grew a bit suspicious and took a second look at the credential checking job: It turned out that the LMS reported success on the SNMP write check because it did not do any checking because there was no credentials setup for it.

So, LMS reports failure on SNMP write access but success on SNMP write credential check -- This, unfortunately, is just one example of how LMS could be confusing. It seems to come down to depend on what the meaning of the word success is.

So I re-entered my default credential sets and applied them to my discovered devices -- That seems to have fixed the SNMP write reachability failure. After that, configuration archive started to work a lot better.

On my way trying to get into the LMS to check something as I was writing this, I got a 404:


Really? An error for missing the favicon? (I didn't have time to figure out what was the issue, so I just restarted dmgtd.)

Tuesday, May 1, 2012

Notes on Drush

My drush commands suddenly stopped working -- I have been too lazy to follow the project, so now I have to dig in to find out why.

As it turns out, the drush command object structure seems to have changed since version 3.x, hence this note to self:

/**
 * Matches a commands array, as returned by drush_get_arguments, with the
 * current command table.
 *
 * Note that not all commands may be discoverable at the point-of-call,
 * since Drupal modules can ship commands as well, and they are
 * not available until after bootstrapping.
 *
 * drush_parse_command returns a normalized command descriptor, which
 * is an associative array with the following entries:
 * - callback: name of function to invoke for this command.
 * - callback arguments: an array of arguments to pass to the calback.
 * - description: description of the command.
 * - arguments: an array of arguments that are understood by the command. for help texts.
 * - options: an array of options that are understood by the command. for help texts.
 * - examples: an array of examples that are understood by the command. for help texts.
 * - scope: one of 'system', 'project', 'site'.
 * - bootstrap: drupal bootstrap level (depends on Drupal major version). -1=no_bootstrap.
 * - core: Drupal major version required.
 * - drupal dependencies: drupal modules required for this command.
 * - drush dependencies: other drush command files required for this command (not yet implemented)
 *
 * @example
 *   drush_parse_command();
 *
 */

Tuesday, March 27, 2012

Drupal 6 jquery_update and jQuery 1.7.1

In experimenting jQuery 1.7.1 with Drupal 6, I found my portman application which uses jQuery UI is broken. Searching on Drupal's website, it seems that the discussion has been going on for a while, dating back to jQuery 1.5. There may be other issues with newer jQuery versions as many Drupal modules are not updated to work with new jQuery.

So, this article is written to record my experiment only. Use the information here with caution if you do.

The jquery_update module would not load the minified jQuery 1.7.1 because the version id in the minified file changes for some reason. I choose to patch the jquery_update module -- hopefully jQuery people don't change the version id too often. Below is the patch.

--- jquery_update.module~       2010-04-23 12:34:39.000000000 -0400
+++ jquery_update.module        2012-03-27 10:54:30.170830649 -0400
@@ -96,7 +96,8 @@
  */
 function jquery_update_get_version($jquery_path = NULL) {
   $version = 0;
-  $pattern = '# * jQuery JavaScript Library v([0-9\.a-z]+)#';
+  $pattern1 = '# * jQuery JavaScript Library v([0-9\.a-z]+)#';
+  $pattern2 = '#/*! jQuery v([0-9\.a-z]+) jquery.com | jquery.org/license */#';

   // No file is passed in so default to the file included with this module.
   if (is_null($jquery_path)) {
@@ -105,7 +106,8 @@

   // Return the version provided by jQuery Update.
   $jquery = file_get_contents($jquery_path);
-  if (preg_match($pattern, $jquery, $matches)) {
+  if (preg_match($pattern1, $jquery, $matches)
+      || preg_match($pattern2, $jquery, $matches)) {
     $version = $matches[1];
   }

Wednesday, February 22, 2012

Difficulties with Google Gadget in WordPress

I had a hard time trying to put my little flickr-show Google Gadget into a WordPress page -- Various versions of the gadget has been used in Google Sites and Blogger pages (also on the sidebar) successfully.

This gadget is very much a proof of concept: The Gadget concept is Google's way for developers to write small apps in XML and JavaScript that could be placed in all kinds of web pages and the Google Desktop. It's not a novel concept but Google seems to be the most open among the companies that have something like it. Google Gadget is simple conceptually: You write an XML module that specifies a number of things, among that relevant to interfacing with the users are (1) a section for options, (2) content area which functions as an HTML/DOM container, (3) JavaScripts that work in the content area and (4) optional message files in XML for multiple language support.

One issue I take with Google's handling of gadgets is inconsistency: The same gadget behaves differently in Google Sites than in a non-Google website where you have to use Google's gadget creator tool to turn the XML modules into an HTML for rendering by user's browsers. Little differences can be very annoying. For example, the gadget creator tool generates three div containers around the iframe with white background color for no apparent reason. I mean, I can understand that Google wants to put their logo on rendered gadgets, but why this obnoxious white background?

Blogger allows gadgets in the sidebar directly. But if you want to put one in your blog entry contents, you have to run it through the gadget creator. Now, on to what I think is a bug somewhere in the Google code cloud. The code the creator tool generated calling Flickr's API function to search for photos returns an empty list in a WordPress page while it works in a Blogger page -- I have later learned that this could be caused by the chaotic use of jQuery in WordPress and many of its plugins, but this seems to be a problem of a different kind as the call does go out through Google's gadgets.io.makeRequest() proxy function and return with results.


To avoid using the Google gadget creator tool, I made changes to make the flickr-show.js module work with or without the Google Gadget API.


On the WordPress side, we observed a situation in which multiple instances of jQuery gets loaded. Which caused chaos for jQuery UI: UI widget functions would randomly disappear from the jQuery namespace. WordPress seems to need a JavaScript library manager badly -- something like the Drupal JavaScript Libraries Manager.

Tuesday, February 21, 2012

An InterMapper Probe in Python

InterMapper ships with Python -- the recent releases come with Python 2.7, making extending it using Python a natural choice.

So when a colleague diagnosed a problem between Cisco ACE and some application servers it load-balances for, I thought about turning his curl script into a probe. Previously I tried to put curl on the Windows 2008 server where our InterMapper software runs, but I didn't get far with that effort. I turned to Python since then when I need to do anything with InterMapper, like writing notifiers and probes.

My notifier and probe code are available on Google Code. My first probe is one that talks to the Cisco xml_agent process, which seems to be supported in more and more Cisco boxes. The probe itself is in the xmlprobe.xml file -- Simple installation instructions are found in there. It connects to the agent on a Cisco box via HTTPS and runs a command configurable either in a configuration file or via InterMapper's "set probe" dialog.

Lessons learned in writing this simple probe: I really hope InterMapper has more documentation about the details of the probe syntaxes. For example, in the section, the arg value doesn't seem to require quotes around it, which leaves the double-quote to be used for quoting individual command line parameters. Also, Windows handles quoted command line parameters differently than Linux -- That caused my much grief as the command used in this case is "show xlate global %(vip)s | count" and the vertical bar caused error when InterMapper runs the probe although it runs fine manually under Cygwin. After searching around in the InterMapper support forums, I happened upon an earlier Q&A topic and found out how to turn on the detailed logging for troubleshooting a command line probe, which revealed the error that I did not see in my manual command line tests.

This probe still looks messy: The JSON configuration data has to be edited manually. It seems that a web-based front-end tool would be helpful. It seems that InterMapper could extend its HTTP API so that the remote access client could be extended through server side plug-ins.

Thursday, February 9, 2012

Working with Cisco LMS Database in Python

Cisco has published its CiscoWorks LAN Management Solution (LMS) database schema (4.2) since version 3.2. JDBC and ODBC are supported methods for accessing data LMS has collected. Setting up ODBC is a bit involved especially when I don't have the privilege to upgrade OS in a box. I don't particularly like Java either. So I thought about getting access to the data locally and possibly provide that data remotely through a web-based interface using an easier-to-use Python-based framework, maybe something like web2py.

So I installed Jython on the Windows Server 2008 box which runs my LMS 4.1 installation, copied down some sample Java code from Cisco and translated that into Python. After a few tries to get Jython to find the right Java class path, it actually worked.

So here is the code (of course, userid and password have to be filled in) that prints a list of devices in the database:


#!/usr/bin/env jython
##
##      Requires this: export CLASSPATH='E:\CSCOpx\lib\classpath'
##


import time
import java.sql


import com.sybase.jdbc2.jdbc.SybDriver


conn = java.sql.DriverManager.getConnection("jdbc:sybase:Tds:localhost:43441?SERVICENAME=cmfDb", userid, password)
print('[%s] INFO: Connection successful...' % time.strftime("%c"))
stmt = conn.createStatement()


query = "SELECT Device_Id, Device_Display_Name, Management_IPAddress FROM Network_Devices"
rs = stmt.executeQuery(query)


cnt = 0
while rs.next():
        cnt += 1
        print("%d. Device Id: %s" % (cnt, rs.getString("Device_Id")))
        print("  Display name: %s" % rs.getString("Device_Display_Name"))
        print("  Management IP address: %s" % rs.getString("Management_IPAddress"))

Friday, February 3, 2012

Obscure Problem with LMS 4.1

Finally got around to put Cisco Prime LMS 4.1 (They seem to be retiring the CiscoWorks brand.) on a Windows 2008 server -- I want to go the appliance route but more work is needed to get a VM in the enterprise environment for that.

First impression: LMS 4.1 looks very different from 3.2.1 on the web-based GUI. Cisco did put effort into modernizing the web-based interface and rearranging components to suite a network manager's work flow rather than around the various pieces that Cisco acquired to make up the LMS bundle. However, one may learn quickly the difference is much less profound under the hood.

Right off the bat, I hit a small snag.

After installation, I enabled HTTPS in Admin by going into Admin » Getting Started » Other System Settings » System Settings » Browser-Server Security Mode, selected Enable HTTPS and applied that setting.

After that, a user browser visiting the LMS server using HTTPS://server-name is redirected to http://server-name:1741/... after login, which produced a 403 (Forbidden) error.

TAC was not much help in this case. After poking my way around the server and the GUI, I think I have fixed the problem:

Go to Admin » Trust Management » Local Server » Browser-Server Security Mode Setup, select Change Setting To: Enable and apply.

It seems to me that both Browser-Server Security Mode from Getting Started and Browser-Server Security Mode Setup in Trust Management should mean exactly the same thing. But apparently they do not do the same thing.