Enterprise Integration Zone is brought to you in partnership with:

I first started working on the IT industry in 2001 and I've been working as software architect and team leader since 2006, mainly on BPM/ERP applications for industries in the agriculture, energy, government, IT, telecom and content management industries, serving roles of Team Leader and software architect. Since 2011, I also started to specialize in SaaS applications and integration on the Cloud. Mariano is a DZone MVB and is not an employee of DZone and has posted 18 posts at DZone. You can read more from them at their website. View Full User Profile

Mule in a Shell: The SSH Connector

01.23.2013
| 15085 views |
  • submit to reddit

Why do I want this?

This connector is mainly aimed to situations in which systems integration requires executing shell commands into a remote system. Examples are:

  • Config changes (passwords, permissions, accounts, etc)
  • Resource provisioning
  • File System operations on non FTP-mapped drives or folders

You can also use this connector as a security gateway. Suppose you’re a system admin and you’re taking a vacation at an all inclusive hotel in Fiji. You receive an urgency call from your boss saying that there’s been a problem and you need to jump into it right now. You’re probably thinking that if you have your notebook or smartphone with you, you could just SSH your way into the server. But what happens if that SSH endpoint is only accessible from within a corporate VPN that’s unreachable from Fiji?. Using this connector plus the power of Mule, you can easily build a secure gateway that exposes the SSH to the outside world as a web client, a chat bot or whatever protocol you need… Cloud is the limit!

What Can I do with it?

The connector’s main features are:

  • Full Duplex communication: Fundamentally, SSH is a bidirectional full duplex protocol, which means that it’s not synchronous like HTTP where you need to send a message for a response to happen. With SSH the remote host might want to tell you something even if you have remained silent. This connector uses a callback flow approach to decouple the “sending” operation from the “receiving” operation.

  • Shell Mode: The connector provides an optional Shell Mode capability. If turned on, the connector will maintain your remote session so that you can execute several commands and still maintain context, similar to a traditional terminal based client such as PuTTY. Using shell mode truly shows the power of the full duplex support. If you just want to execute a single command, then you can turn this off and save resources.

  • Connection multiplexing: Another particular feature of SSH is that you can have several users logged into the same server. The base connection is represented by the concept of a session and each user operates over a Channel. This connector completely hides this complexity for you while providing a similar model in which you can have multiple users operating over the same client.

I’m sold! How do I use it?

First, you need to visit the Mule Forge site and follow the installation guide following this link.

Now that we’re all set, let’s start by adding the namespace:

<mule xmlns="http://www.mulesoft.org/schema/mule/core"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:ssh="http://www.mulesoft.org/schema/mule/sshmultiplexedconnector"
      xsi:schemaLocation="
        http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
        http://www.mulesoft.org/schema/mule/ssh http://www.mulesoft.org/schema/mule/sshmultiplexedconnector/1.0/mule-sshmultiplexedconnector.xsd">

Now, we config the connector:

<ssh:config host="ssh.mycompany.com" port="22" timeout="6000" callbackFlowName="callback" shellMode="true" />

As you can see the configuration is pretty descriptive and straight forward. It’s pretty much about:

  • Host
  • TCP port
  • Timeout (in milliseconds)
  • Callback flow name (to support full duplex, carry on reading for a full example)
  • Shell Mode: Boolean property to enable (or not) shell mode. We’ll use it in this example.

Now, let’s send a couple of commands!

<flow name="exampleFlow">
 <ssh:send username="${ssh.user}" password="${ssh.pass}" content="cd test" breakLine="true" />
 <ssh:send username="${ssh.user}" password="${ssh.pass}" content="cat helloWorld.txt" breakLine="true"/>
</flow>

So what this code doing is navigating to a folder named test and output the contents of the helloWorld.txt file. Since we’re using shell mode, the second command is still aware of the navigation performed in the first command and therefore can output the file. If shell mode were disabled, then the second command would fail because the user’s location would be set to $HOME again.

Now that we’re clear on what this flow does, let’s take a closer look at the parameters:

  • Username and password: Besides the obvious, the nice thing about this parameters is that the connector will use the username to multiplex and reuse the underlying channel associated to this username.

  • Content: The payload you want to get across

  • breakLine: This parameter is optional and defaults to false. If true, it will add a ‘\n’ character to the end of the content. This is because if you want to execute a command, the remote shell needs you to hit enter to end the line. So, if you’re payload is fixed like in the example, adding a break to end the line automatically comes handy. If you’re getting the content from a web client, chat channel or whatever source that will include the line break, or if you simply don’t need it, then don’t set this value.

And how do I read the response? Defining the callback flow that was specified in the connector’s config:

<flow name="callback">
   <logger message="sent to #[header:INBOUND:SSH_CALLBACK_USER], message says: #[payload]" />
</flow>

There’re two things to notice about this flow:

  • The name matches the config’s callbackFlowName property
  • The message payload contains the server response and the SSH_CALLBACK_USER inbound property has the username to whom the message was sent (remember that connections are full duplex and multiplexed, so concurrency makes it impossible to assure the order in which responses will arrive)

So, we’re pretty much done here, the last thing is to release the connection once we’re done using it:

<flow name="release">
 <ssh:release username="${ssh.user}"/>
</flow>

Notice that the release operation has the username as a mandatory parameter. This is because the connector is a multiplexed, and while user A may be ready to free some resources, users B and C might still be operating.

That’s all folks! Please visit the MuleForge for further info and don’t hesitate to share questions or thoughts about this connector. We look forward to your feedback.







Published at DZone with permission of Mariano Gonzalez, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)