Tuesday, February 3, 2015

Ganymed SSH2 Cisco Router | Using Ganymed SSH2 to Configure Cisco Routes/Switches

Configure Cisco Routers/Switches Using SSH

I have some use cases where SSH is used to configure Cisco routers/switches. For example, to enable a WAN interface, the following commands are executed:
en
password
configure terminal 
int Fa0/0/0
ip address 172.0.0.1255.255.255.252
description Link to 408
bandwidth 8000
service-policy output shape-8Mb
no shutdown
end

copy run start
exit
 

Apache Camel SSH Component

Apache Camel has a SSH component. However, I found that it did not work when configuring Cisco routers/switches.
The problem is that it cannot execute the "en password" command.

Ganymed SSH2 Library

Fortunately I could solve it by using another SSH library called Ganymed.
The following is the code I used to execute IOS commands.

 



private static final String PROMPT_SYMBOL = "%";
private static final char ERROR_SYMBOL = '^';
private static final String ACCESS_DENIED_MESSAGE = "Access denied";
private static final int MAX_OUTPUT_BUFFER_SIZE = 1024 * 1024;

public void executeCommand(String host, String username, String password, int timeout, String command) throws IOException, AccessDeniedException
{
  Connection connection = new Connection(host);
  
  connection.connect(null, timeout, timeout);
  
  boolean authenticated = connection.authenticateWithPassword(username, password);
  
  if (!authenticated)
    return;
  
  Session session = connection.openSession();
  session.startShell();
  
  executeCommand(session, timeout, command);
}
Hotels.com 
private SshResponse executeCommand(Session session, int timeout, String command) throws IOException, AccessDeniedException
{
  OutputStream in = session.getStdin();

  in.write(command.getBytes());
  
  InputStream stdout = session.getStdout();
  InputStream stderr = session.getStderr();
  
  StringBuilder sb = new StringBuilder();
  boolean valid = false;
  String line = null;

  boolean flag = true;
  while (flag)
  {
    int conditions = session.waitForCondition(ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA | ChannelCondition.EOF, timeout);

    if ((conditions & ChannelCondition.TIMEOUT) != 0)
    {
      break;
    }

    if ((conditions & ChannelCondition.EOF) != 0)
    {
      if ((conditions & (ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA)) == 0)
      {
        break;
      }
    }

    BufferedReader reader = null;
    try
    {
      if ((ChannelCondition.STDOUT_DATA & conditions) != 0)
      {
        reader = new BufferedReader(new InputStreamReader(stdout));
      }
      else
      {
        reader = new BufferedReader(new InputStreamReader(stderr));
      }

      //Reader.readLine() may hang if 'exit' is not added to the command as the last line (use the 'exit' to exit the shell)
      
      boolean toAppend = true;
      
      while (true)
      {
        line = reader.readLine();
        
        if (line == null)
        {
          valid = true;
          
          flag = false;
          break;
        }
        
        if (toAppend)
        {
          toAppend = this.append(sb, line);
        }
        
        if (line.trim().startsWith(PROMPT_SYMBOL))
        {
          if (line.trim().indexOf(ERROR_SYMBOL) >= 0)
          {
            valid = false;
            
            flag = false;
            break;
          }
          else if (line.trim().contains(ACCESS_DENIED_MESSAGE))
          {
            throw new AccessDeniedException(line.trim());
          }
        }
        
        line = reader.readLine();
      }
    }
    finally
    {
      if (reader != null)
        reader.close();
    }
  }
  
  String message = sb.toString().trim();
  
  SshResponse response = new SshResponse();
  
  response.setCommand(command);
  response.setValid(valid);
  response.setOut(message);
  //keep all output
  //r4(config)#int Fastethernet1/0
  //               ^
  //% Invalid input detected at '^' marker.
  response.setErr(message);
  
  return response;
}
private boolean append(StringBuilder sb, String line)
{
  if (sb.length() >= MAX_OUTPUT_BUFFER_SIZE)
  {
    sb.setLength(MAX_OUTPUT_BUFFER_SIZE - 3);
    sb.append("...");
    
    return false;
  }
  
  if (sb.length() + line.length() > MAX_OUTPUT_BUFFER_SIZE)
  {
    //Minimum abbreviation width is 4
    if (MAX_OUTPUT_BUFFER_SIZE - sb.length() < 4)
    {
      sb.setLength(MAX_OUTPUT_BUFFER_SIZE - 3);
      sb.append("...");
    }
    else
    {
      String abbreviated = StringUtils.abbreviate(line, MAX_OUTPUT_BUFFER_SIZE - sb.length());
      
      sb.append(abbreviated);
    }
    
    sb.append('\n');
    
    return false;
  }
  
  sb.append(line);
  sb.append('\n');
  
  return true;
}

Keep in mind that the last command "exit" should not be omitted otherwise the SSH session may hang up for ever.


Create a Successful Online Store at Bigcommerce! Try it Free Now!

Saturday, January 31, 2015

Unix - Find Command Argument List Too Long

When I was trying to use the following script to find all files under a directory and perform some task, I got arg list too long error.
for i in `find $WORKDIR/*Alarm* -mtime 1 -type f`
do
some task
done
After I changed to use below script, it worked as expected.
for i in `find $WORKDIR -name ‘*Alarm*’ -mtime 1 -type f`
do
some task
done


Create a Successful Online Store at Bigcommerce! Try it Free Now!

Friday, January 30, 2015

Oracle - Function Based Index

A function-based index computes the value of an expression that involves one or more columns and stores it in the index. The index expression can be an arithmetic expression or an expression that contains a SQL function, PL/SQL function, package function, or C callout.[1]
Oracle generates a column name of the format "SYS_NC?????$" in all_ind_columns table.

If you want to find the corresponding expression for the index, you can like this.

Execute:

SELECT a.index_name, a.column_name, b.column_expression FROM all_ind_columns a LEFT JOIN all_ind_expressions b ON A.index_name = b.index_name AND A.column_position = b.column_position WHERE a.index_name='table_name$unique_index_name';



Result:

table_name$unique_index_name  SYS_NC00031$   TRUNC("UPDATE_DATE")


References


  1. https://docs.oracle.com/cd/E11882_01/appdev.112/e41502/adfns_indexes.htm#ADFNS00505


Create a Successful Online Store at Bigcommerce! Try it Free Now!

Telerik Winforms 2010 SP1 - RadGridView - Populate ComboBoxColumn Data Source at Runtime

Assume you have a grid view radGridView1 and you have a combobox column in it. The column's header text is "Status".
You could use the following code to populate its data source at runtime.
void radGridView1_CellEditorInitialized(object sender, GridViewCellEventArgs e)
{
  if (e.Column.HeaderText == "Status")
  {
    RadComboBoxEditor editor = this.radGridView1.ActiveEditor as RadComboBoxEditor;
    RadComboBoxEditorElement element = editor.EditorElement as RadComboBoxEditorElement;

    element.DataSource = new string[] { "UP", "DOWN" };    

    element.SelectedValue = null;
    element.SelectedValue = this.radGridView1.CurrentCell.Value;
  }
}


Create a Successful Online Store at Bigcommerce! Try it Free Now!

Spark2.5.8 JID Nick Name | Spark 2.5.8 - Use JID Instead of Nick Name in Chat UI

Customize Spark: Use JID instead Nick Name

By default, Spark uses nick name (e.g. admin) in its private/group chat windows. If you want to use JID (e.g. admin@server/Spark) instead, consider the following two ways:
1.
private String getJidFromPresencePacket(Presence p)
{
  Collection<PacketExtension> extensions = p.getExtensions();      
  
  if (extensions instanceof List && !extensions.isEmpty())
  {
    Object obj = ((List<?>)extensions).get(0);
    
    if (obj instanceof MUCUser)
    {
      MUCUser.Item item = ((MUCUser)obj).getItem();
      
      if (item != null)
      {
        return item.getJid();
      }
    }
  }
  
  return p.getFrom();
}
2. a simpler way
private String getJidFromPresencePacket(Presence p)
{
  MUCUser mucUser = (MUCUser)p.getExtension("x", "http://jabber.org/protocol/muc#user");
  
  if (mucUser != null)
  {
    MUCUser.Item item = mucUser.getItem();
    
    if (item != null)
    {
      return item.getJid();
    }
  }      
  
  return p.getFrom();
}

XMPP JID

A JID consists of three main parts:
  1. The node identifier (optional)
  2. The domain identifier (required)
  3. The resource identifier (optional)

If you want to use only the node id and the domain id in your UI, you can use the method below to extract them from a JID:
StringUtils.parseBareAddress(JID)



Create a Successful Online Store at Bigcommerce! Try it Free Now!