Skip to content

Commit 3aec240

Browse files
committed
changes for 1.1.0
1 parent 92c1618 commit 3aec240

File tree

4 files changed

+824
-325
lines changed

4 files changed

+824
-325
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ local.properties
3535
# Other Tooling #
3636
.classpath
3737
.project
38-
target
38+
target/
3939
.idea
4040
*.iml
4141

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
<dependency>
5454
<groupId>com.microsoft.azure</groupId>
5555
<artifactId>azure</artifactId>
56-
<version>1.0.0</version>
56+
<version>1.1.0</version>
5757
</dependency>
5858
<dependency>
5959
<groupId>org.eclipse.jgit</groupId>

src/main/java/com/microsoft/azure/management/samples/SSHShell.java

+191
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@
66

77
package com.microsoft.azure.management.samples;
88

9+
import com.jcraft.jsch.Channel;
10+
import com.jcraft.jsch.ChannelExec;
11+
import com.jcraft.jsch.ChannelSftp;
912
import com.jcraft.jsch.ChannelShell;
1013
import com.jcraft.jsch.JSch;
1114
import com.jcraft.jsch.JSchException;
15+
import com.jcraft.jsch.KeyPair;
1216
import com.jcraft.jsch.Session;
1317
import expect4j.Closure;
1418
import expect4j.Expect4j;
@@ -17,7 +21,10 @@
1721
import expect4j.matches.RegExpMatch;
1822
import org.apache.oro.text.regex.MalformedPatternException;
1923

24+
import java.io.BufferedOutputStream;
25+
import java.io.ByteArrayOutputStream;
2026
import java.io.IOException;
27+
import java.io.InputStream;
2128
import java.util.ArrayList;
2229
import java.util.Hashtable;
2330
import java.util.List;
@@ -105,6 +112,116 @@ public String runCommands(List<String> commands) throws Exception {
105112
return output;
106113
}
107114

115+
/**
116+
* Executes a command on the remote host.
117+
*
118+
* @param command the command to be executed
119+
* @param getExitStatus return the exit status captured in the stdout
120+
* @param withErr capture the stderr as part of the output
121+
* @return the content of the remote output from executing the command
122+
* @throws Exception exception thrown
123+
*/
124+
public String executeCommand(String command, Boolean getExitStatus, Boolean withErr) throws Exception {
125+
String result = "";
126+
String resultErr = "";
127+
128+
Channel channel = this.session.openChannel("exec");
129+
((ChannelExec) channel).setCommand(command);
130+
InputStream commandOutput = channel.getInputStream();
131+
InputStream commandErr = ((ChannelExec) channel).getErrStream();
132+
channel.connect();
133+
byte[] tmp = new byte[4096];
134+
while (true) {
135+
while (commandOutput.available() > 0) {
136+
int i = commandOutput.read(tmp, 0, 4096);
137+
if (i < 0) {
138+
break;
139+
}
140+
result += new String(tmp, 0, i);
141+
}
142+
while (commandErr.available() > 0) {
143+
int i = commandErr.read(tmp, 0, 4096);
144+
if (i < 0) {
145+
break;
146+
}
147+
resultErr += new String(tmp, 0, i);
148+
}
149+
if (channel.isClosed()) {
150+
if (commandOutput.available() > 0) {
151+
continue;
152+
}
153+
if (getExitStatus) {
154+
result += "exit-status: " + channel.getExitStatus();
155+
if (withErr) {
156+
result += "\n With error:\n" + resultErr;
157+
}
158+
}
159+
break;
160+
}
161+
try {
162+
Thread.sleep(100);
163+
} catch (Exception ee) { }
164+
}
165+
channel.disconnect();
166+
167+
return result;
168+
}
169+
170+
/**
171+
* Downloads the content of a file from the remote host as a String.
172+
*
173+
* @param fileName the name of the file for which the content will be downloaded
174+
* @param fromPath the path of the file for which the content will be downloaded
175+
* @param isUserHomeBased true if the path of the file is relative to the user's home directory
176+
* @return the content of the file
177+
* @throws Exception exception thrown
178+
*/
179+
public String download(String fileName, String fromPath, boolean isUserHomeBased) throws Exception {
180+
ChannelSftp channel = (ChannelSftp) this.session.openChannel("sftp");
181+
channel.connect();
182+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
183+
BufferedOutputStream buff = new BufferedOutputStream(outputStream);
184+
String absolutePath = isUserHomeBased ? channel.getHome() + "/" + fromPath : fromPath;
185+
channel.cd(absolutePath);
186+
channel.get(fileName, buff);
187+
188+
channel.disconnect();
189+
190+
return outputStream.toString();
191+
}
192+
193+
/**
194+
* Creates a new file on the remote host using the input content.
195+
*
196+
* @param from the byte array content to be uploaded
197+
* @param fileName the name of the file for which the content will be saved into
198+
* @param toPath the path of the file for which the content will be saved into
199+
* @param isUserHomeBased true if the path of the file is relative to the user's home directory
200+
* @param filePerm file permissions to be set
201+
* @throws Exception exception thrown
202+
*/
203+
public void upload(InputStream from, String fileName, String toPath, boolean isUserHomeBased, String filePerm) throws Exception {
204+
ChannelSftp channel = (ChannelSftp) this.session.openChannel("sftp");
205+
channel.connect();
206+
String absolutePath = isUserHomeBased ? channel.getHome() + "/" + toPath : toPath;
207+
208+
String path = "";
209+
for (String dir : absolutePath.split("/")) {
210+
path = path + "/" + dir;
211+
try {
212+
channel.mkdir(path);
213+
} catch (Exception ee) {
214+
}
215+
}
216+
channel.cd(absolutePath);
217+
channel.put(from, fileName);
218+
if (filePerm != null) {
219+
channel.chmod(Integer.parseInt(filePerm), absolutePath + "/" + fileName);
220+
}
221+
222+
channel.disconnect();
223+
}
224+
108225
/**
109226
* Closes shell.
110227
*/
@@ -130,4 +247,78 @@ public void run(ExpectState expectState) throws Exception {
130247
}
131248
};
132249
}
250+
251+
/**
252+
* Automatically generate SSH keys.
253+
* @param passPhrase the byte array content to be uploaded
254+
* @param comment the name of the file for which the content will be saved into
255+
* @return SSH public and private key
256+
* @throws Exception exception thrown
257+
*/
258+
public static SshPublicPrivateKey generateSSHKeys(String passPhrase, String comment) throws Exception {
259+
JSch jsch = new JSch();
260+
KeyPair keyPair = KeyPair.genKeyPair(jsch, KeyPair.RSA);
261+
ByteArrayOutputStream privateKeyBuff = new ByteArrayOutputStream(2048);
262+
ByteArrayOutputStream publicKeyBuff = new ByteArrayOutputStream(2048);
263+
264+
keyPair.writePublicKey(publicKeyBuff, (comment != null) ? comment : "SSHCerts");
265+
266+
if (passPhrase == null || passPhrase.isEmpty()) {
267+
keyPair.writePrivateKey(privateKeyBuff);
268+
} else {
269+
keyPair.writePrivateKey(privateKeyBuff, passPhrase.getBytes());
270+
}
271+
272+
return new SshPublicPrivateKey(privateKeyBuff.toString(), publicKeyBuff.toString());
273+
}
274+
275+
/**
276+
* Internal class to retain the generate SSH keys.
277+
*/
278+
public static class SshPublicPrivateKey {
279+
private String sshPublicKey;
280+
private String sshPrivateKey;
281+
282+
/**
283+
* Constructor.
284+
* @param sshPrivateKey SSH private key
285+
* @param sshPublicKey SSH public key
286+
*/
287+
public SshPublicPrivateKey(String sshPrivateKey, String sshPublicKey) {
288+
this.sshPrivateKey = sshPrivateKey;
289+
this.sshPublicKey = sshPublicKey;
290+
}
291+
292+
/**
293+
* Get SSH public key.
294+
* @return public key
295+
*/
296+
public String getSshPublicKey() {
297+
return sshPublicKey;
298+
}
299+
300+
/**
301+
* Get SSH private key.
302+
* @return private key
303+
*/
304+
public String getSshPrivateKey() {
305+
return sshPrivateKey;
306+
}
307+
308+
/**
309+
* Set SSH public key.
310+
* @param sshPublicKey public key
311+
*/
312+
public void setSshPublicKey(String sshPublicKey) {
313+
this.sshPublicKey = sshPublicKey;
314+
}
315+
316+
/**
317+
* Set SSH private key.
318+
* @param sshPrivateKey private key
319+
*/
320+
public void setSshPrivateKey(String sshPrivateKey) {
321+
this.sshPrivateKey = sshPrivateKey;
322+
}
323+
}
133324
}

0 commit comments

Comments
 (0)