ssh2shell 2.0.3 → 2.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,14 +4,39 @@ ssh2shell
4
4
 
5
5
  Ssh2shell uses [ssh2](https://www.npmjs.org/package/ssh2) to open a ssh shell session to a host/s to run multiple commands and process the responses.
6
6
 
7
- Installation:
7
+ Index:
8
+ ------------
9
+ * [Instalation](#installation-)
10
+ * [Minimal Example](#minimal-example-)
11
+ * [Host Configuration](#host-configuration-)
12
+ * [ssh2shell API](#ssh2shell-api-)
13
+ * [Usage](#usage-)
14
+ * [Authentication](#authentication-)
15
+ * [Default Cyphers](#default-cyphers-)
16
+ * [Fingerprint Validation](#fingerprint-validation-)
17
+ * [Keyboard-interactive](#keyboard-interactive-)
18
+ * [Trouble shooting](#trouble-shooting-)
19
+ * [Verbose and Debug](#verbose-and-debug-)
20
+ * [Notification commands](#notification-commands-)
21
+ * [Sudo and su Commands](#sudo-and-su-commands-)
22
+ * [Prompt detection override](#prompt-detection-override-)
23
+ * [Text regular expression filters](#text-regular-expression-filters-)
24
+ * [Responding to non-standard command prompts](#responding-to-non-standard-command-prompts-)
25
+ * [Command Time-out event](#command-time-out-event-)
26
+ * [Multiple Primary Hosts](#multiple-primary-hosts-)
27
+ * [Tunnelling nested host objects](#tunnelling-nested-host-objects-)
28
+ * [Event Handlers](#event-handlers-)
29
+ * [Bash scripts on the fly](#bash-scripts-on-the-fly-)
30
+
31
+
32
+ [Installation: ^](#index)
8
33
  ------------
9
34
  ```
10
35
  npm install ssh2shell
11
36
  ```
12
37
 
13
38
 
14
- Minimal Example:
39
+ [Minimal Example: ^](#index)
15
40
  ------------
16
41
  ```javascript
17
42
  //host configuration with connection settings and commands
@@ -35,7 +60,7 @@ SSH.connect(callback);
35
60
  ```
36
61
 
37
62
 
38
- Host Configuration:
63
+ [Host Configuration: ^](#index)
39
64
  ------------
40
65
  SSH2Shell requires an object with the following structure:
41
66
  ```javascript
@@ -109,8 +134,9 @@ host = {
109
134
  readyMessage: "Ready",
110
135
  closedMessage: "Closed",
111
136
 
112
- //Optional: Host event handlers .
113
- //Host defined event handlers are set as the default event handlers.
137
+ //Optional: Host event handlers.
138
+ //Host defined event handlers are cleared with each change of host.
139
+ //Default and instance event handlers are global to all hosts and are not cleared.
114
140
 
115
141
  //Optional:
116
142
  onKeyboardInteractive: function(name, instructions, instructionsLang, prompts, finish){
@@ -191,7 +217,7 @@ host = {
191
217
  variables and the current array of commands for the host. The sshObj.commands array changes with each host connection.
192
218
 
193
219
 
194
- ssh2shell API
220
+ [ssh2shell API: ^](#index)
195
221
  -------------
196
222
  SSH2Shell extends events.EventEmitter
197
223
 
@@ -214,11 +240,9 @@ SSH2Shell extends events.EventEmitter
214
240
  * .command is the current command being run until a new prompt is detected and the next command replaces it.
215
241
 
216
242
 
217
- Usage:
218
- ======
219
- Connecting to a single host:
220
- ----------------------------
221
-
243
+ [Usage: ^](#index)
244
+ --------
245
+ *Connecting to a single host*
222
246
 
223
247
  *app.js*
224
248
  ```javascript
@@ -248,7 +272,7 @@ SSH.connect(callback);
248
272
  ```
249
273
 
250
274
 
251
- Authentication:
275
+ [Authentication: ^](#index)
252
276
  ---------------
253
277
  * Each host authenticates with its own host.server parameters.
254
278
  * When using key authentication you may require a valid pass phrase if your key was created with one.
@@ -258,7 +282,7 @@ Authentication:
258
282
  function...) or host.onKeyboardInteractive() must be defined.
259
283
  * Set the default cyphers and keys.
260
284
 
261
- Default Cyphers:
285
+ [Default Cyphers: ^](#index)
262
286
  ---------------
263
287
  Default Cyphers and Keys used in the initial ssh connection can be redefined by setting the ssh2.connect.algorithms through the host.server.algorithms option.
264
288
  As with this property all ssh2.connect properties are set in the host.server object.
@@ -298,7 +322,7 @@ var host = {
298
322
  }
299
323
  ```
300
324
 
301
- Fingerprint Validation:
325
+ [Fingerprint Validation: ^](#index)
302
326
  ---------------
303
327
  At connection time the hash of the server’s public key can be compared with the hash the client had previously recorded
304
328
  for that server. This stops "man in the middle" attacks where you are redirected to a different server as you connect
@@ -366,14 +390,14 @@ host.server.hashMethod only supports md5 or sha1 according to the current SSH2 d
366
390
  undesired results.__
367
391
 
368
392
 
369
- Keyboard-interactive
393
+ [Keyboard-interactive: ^](#index)
370
394
  ----------------------
371
395
  Keyboard-interactive authentication is available when both host.server.tryKeyboard is set to true and the event handler
372
396
  keyboard-interactive is defined as below. The keyboard-interactive event handler can only be used on the first connection.
373
397
 
374
398
  Also see [test/keyboard-interactivetest.js](https://github.com/cmp-202/ssh2shell/blob/master/test/keyboard-interactivetest.js) for the full example
375
399
 
376
- *Defining the event handler:*
400
+ *Defining the event handler*
377
401
  ```javascript
378
402
  //this is required
379
403
  host.server.tryKeyboard = true;
@@ -420,7 +444,7 @@ host = {
420
444
  ```
421
445
 
422
446
 
423
- Trouble shooting:
447
+ [Trouble shooting: ^](#index)
424
448
  -----------------
425
449
 
426
450
  * Adding msg command `"msg:Doing something"` to your commands array at key points will help you track the sequence of
@@ -440,7 +464,7 @@ Trouble shooting:
440
464
  (1000 = 1 sec)
441
465
 
442
466
 
443
- Verbose and Debug:
467
+ [Verbose and Debug: ^](#index)
444
468
  ------------------
445
469
  * When host.verbose is set to true each command complete raises a msg event outputting the response text.
446
470
  * When host.debug is set to true each process step raises a msg event to help identify what the internal processes were.
@@ -454,7 +478,7 @@ Add your own verbose messages as follows:
454
478
  Add your own debug messages as follows:
455
479
  `if(this.sshObj.debug){this.emit("msg", this.sshObj.server.host + ": eventName");} //where eventName is the text identifying what happened`
456
480
 
457
- Notification commands:
481
+ [Notification commands: ^](#index)
458
482
  ----------------------
459
483
  There are two notification commands that are added to the host.commands array but are not run as a command on the host.
460
484
 
@@ -463,7 +487,7 @@ There are two notification commands that are added to the host.commands array bu
463
487
  * The reason for not using echo or printf commands as a normal command is that you see both the command and the message in the sessionText which is pointless when all you want is the message.
464
488
 
465
489
 
466
- Sudo and su Commands:
490
+ [Sudo and su Commands: ^](#index)
467
491
  --------------
468
492
  It is possible to use `sudo [command]`, `sudo su`, `su [username]` and `sudo -u [username] -i`.
469
493
  Sudo commands uses the password for the current session and is processed by ssh2shell. Su on the other hand uses the password
@@ -475,7 +499,7 @@ See: [su VS sudo su VS sudo -u -i](http://johnkpaul.tumblr.com/post/19841381351/
475
499
  See: [test/sudosutest.js](https://github.com/cmp-202/ssh2shell/blob/master/test/sudosutest.js) for a working code example.
476
500
 
477
501
 
478
- Prompt detection override:
502
+ [Prompt detection override: ^](#index)
479
503
  -------------------------
480
504
  Used to detect different prompts.
481
505
 
@@ -487,7 +511,7 @@ These are optional settings.
487
511
  ```
488
512
 
489
513
 
490
- Text regular expression filters:
514
+ [Text regular expression filters: ^](#index)
491
515
  -------------------------------
492
516
  There are two regular expression filters that remove unwanted text from response data.
493
517
 
@@ -502,7 +526,7 @@ host.textColorFilter = "(\[{1}[0-9;]+m{1})"
502
526
  ```
503
527
 
504
528
 
505
- Responding to non-standard command prompts:
529
+ [Responding to non-standard command prompts: ^](#index)
506
530
  ----------------------
507
531
  In host.onCommandProcessing event handler the prompt can be detected and a response can be sent via `stream.write("y\n")`.
508
532
 
@@ -542,7 +566,7 @@ __*Note:*
542
566
  If no prompt is detected `commandTimeout` will be raised after the idleTimeOut period.__
543
567
 
544
568
 
545
- Command Time-out event
569
+ [Command Time-out event: ^](#index)
546
570
  ---------------
547
571
  When onCommandTimeout event triggers after the host.idleTimeOut is exceeded.
548
572
  This is because there is no new data and no prompt is detected to run the next command.
@@ -611,7 +635,79 @@ SSH.connect();
611
635
  ```
612
636
 
613
637
 
614
- Tunnelling nested host objects:
638
+ [Multiple Primary Hosts: ^](#index)
639
+ -----------------------
640
+ Multiple hosts can be connected to one after the other as you would connecting to a single host.
641
+ Each host config is independant of each other but can share thingsa like commands and handlers.
642
+ Each host config is added to an array of hosts that is passed to the constructor.
643
+ The final `sessionText` contains the output from all the hosts.
644
+
645
+ ```javascript
646
+ var dotenv = require('dotenv').config(),
647
+ debug = false,
648
+ verbose = false
649
+
650
+
651
+ //Host objects:
652
+ var host1 = {
653
+ server: {
654
+ host: process.env.HOST,
655
+ port: process.env.PORT,
656
+ userName: process.env.USER_NAME,
657
+ password: process.env.PASSWORD
658
+ },
659
+ commands: ["echo Host_1"],
660
+ connectedMessage: "Connected to host1",
661
+ debug: debug,
662
+ verbose: verbose
663
+ },
664
+
665
+ host2 = {
666
+ server: {
667
+ host: process.env.SERVER2_HOST,
668
+ port: process.env.PORT,
669
+ userName: process.env.SERVER2_USER_NAME,
670
+ password: process.env.SERVER2_PASSWORD
671
+ },
672
+ commands: ["echo Host_2"],
673
+ connectedMessage: "Connected to host2",
674
+ debug: debug,
675
+ verbose: verbose
676
+ },
677
+
678
+ host3 = {
679
+ server: {
680
+ host: process.env.SERVER3_HOST,
681
+ port: process.env.PORT,
682
+ userName: process.env.SERVER3_USER_NAME,
683
+ password: process.env.SERVER3_PASSWORD
684
+ },
685
+ commands: ["echo Host_3"],
686
+ connectedMessage: "Connected to host3",
687
+ debug: debug,
688
+ verbose: verbose,
689
+ //Event handler only used by this host
690
+ onCommandComplete: function( command, response, sshObj ) {
691
+ this.emit("msg", sshObj.server.host + ": commandComplete only used on this host");
692
+ }
693
+ }
694
+
695
+ var SSH2Shell = require ('ssh2shell'),
696
+ SSH = new SSH2Shell([host1,host2,host3]),
697
+ callback = function( sessionText ){
698
+ console.log ( "-----Callback session text:\n" + sessionText);
699
+ console.log ( "-----Callback end" );
700
+ }
701
+
702
+ SSH.on ('end', function( sessionText, sshObj ) {
703
+ this.emit("msg", sshObj.server.host + ": onEnd every host");
704
+ })
705
+
706
+ SSH.connect(callback);
707
+ ```
708
+
709
+
710
+ [Tunnelling nested host objects: ^](#index)
615
711
  ---------------------------------
616
712
  `hosts: [ host1, host2]` setting can make multiple host connections possible.
617
713
  Each host config object has its own server settings, commands, command handlers and
@@ -820,7 +916,7 @@ SSH.connect();
820
916
  ```
821
917
 
822
918
 
823
- Event Handlers:
919
+ [Event Handlers: ^](#index)
824
920
  ---------------
825
921
  There are a number of event handlers that enable you to add your own code to be run when those events are triggered.
826
922
  Most of these you have already encountered in the host object. You do not have to add event handlers unless you want
@@ -940,7 +1036,7 @@ ssh2shell.on ("Unpipe", function onUnpipe(source){
940
1036
  });
941
1037
  ```
942
1038
 
943
- Bash scripts on the fly:
1039
+ [Bash scripts on the fly: ^](#index)
944
1040
  ------------------------
945
1041
  If the commands you need to run would be better suited to a bash script as part of the process it is possible to generate
946
1042
  or get the script on the fly. You can echo/printf the script content into a file as a command, ensure it is executable,
package/first.log ADDED
@@ -0,0 +1,30 @@
1
+ Welcome to Ubuntu 18.04.1 LTS (GNU/Linux 4.15.0-191-generic x86_64)
2
+
3
+ * Documentation: https://help.ubuntu.com
4
+ * Management: https://landscape.canonical.com
5
+ * Support: https://ubuntu.com/advantage
6
+
7
+ System information as of Wed Aug 17 20:13:26 NZST 2022
8
+
9
+ System load: 0.29 Processes: 100
10
+ Usage of /: 63.3% of 6.28GB Users logged in: 0
11
+ Memory usage: 5% IP address for enp0s3: 192.168.0.117
12
+ Swap usage: 0%
13
+
14
+ * Super-optimized for small spaces - read how we shrank the memory
15
+ footprint of MicroK8s to make it the smallest full K8s around.
16
+
17
+ https://ubuntu.com/blog/microk8s-memory-optimisation
18
+
19
+ 130 packages can be updated.
20
+ 3 updates are security updates.
21
+
22
+ New release '20.04.4 LTS' available.
23
+ Run 'do-release-upgrade' to upgrade to it.
24
+
25
+
26
+ banner content
27
+ Last login: Wed Aug 17 20:13:10 2022 from 192.168.0.6
28
+ user@ubuntu:~$ echo host pipe
29
+ host pipe
30
+ user@ubuntu:~$
package/lib/ssh2shell.js CHANGED
@@ -420,7 +420,7 @@
420
420
  if (this.sshObj.debug) {
421
421
  this.emit('msg', this.sshObj.server.host + ": Remove previous event handlers");
422
422
  }
423
- this._removeEvents();
423
+ this._removeListeners();
424
424
  this._connections.push(this.sshObj);
425
425
  this.sshObj = nextHost;
426
426
  return this._initiate(this._sshConnect);
@@ -435,7 +435,8 @@
435
435
  if (this.sshObj.debug) {
436
436
  this.emit('msg', this.sshObj.server.host + ": Remove previous event handlers");
437
437
  }
438
- this._removeEvents();
438
+ this.emit('end', this._primaryhostSessionText, this.sshObj);
439
+ this._removeListeners();
439
440
  }
440
441
  this.sshObj = this._hosts.shift();
441
442
  this._primaryhostSessionText = this.sshObj.server.host + ": ";
@@ -553,7 +554,7 @@
553
554
  return this._stream.close();
554
555
  };
555
556
 
556
- SSH2Shell.prototype._removeEvents = function() {
557
+ SSH2Shell.prototype._removeListeners = function() {
557
558
 
558
559
  /*
559
560
  if @sshObj.debug
@@ -568,19 +569,36 @@
568
569
  @.emit 'msg', "commandTimeout: " + (@.listenerCount 'commandTimeout')
569
570
  @.emit 'msg', "msg: " + (@.listenerCount 'msg')
570
571
  */
572
+ if (typeof this.sshObj.onKeyboardInteractive === 'function') {
573
+ this.removeListener("keyboard-interactive", this.sshObj.onKeyboardInteractive);
574
+ }
575
+ if (typeof this.sshObj.onStderrData === 'function') {
576
+ this.removeListener("stderrData", this.sshObj.onStderrData);
577
+ }
571
578
  if (typeof this.sshObj.onData === 'function') {
572
579
  this.removeListener("data", this.sshObj.onData);
573
580
  }
574
- this.removeAllListeners("error");
581
+ if (typeof this.sshObj.onError === 'function') {
582
+ this.removeListener("error", this.sshObj.onError);
583
+ }
575
584
  if (typeof this.sshObj.onStderrData === 'function') {
576
585
  this.removeListener("stderrData", this.sshObj.onStderrData);
577
586
  }
578
- this.removeAllListeners('end');
579
- this.removeAllListeners('keyboard-interactive');
580
- this.removeAllListeners('commandProcessing');
581
- this.removeAllListeners('commandComplete');
582
- this.removeAllListeners('commandTimeout');
583
- this.removeAllListeners('msg');
587
+ if (typeof this.sshObj.onEnd === 'function') {
588
+ this.removeListener("end", this.sshObj.onEnd);
589
+ }
590
+ if (typeof this.sshObj.onCommandProcessing === 'function') {
591
+ this.removeListener("commandProcessing", this.sshObj.onCommandProcessing);
592
+ }
593
+ if (typeof this.sshObj.onCommandComplete === 'function') {
594
+ this.removeListener("commandComplete", this.sshObj.onCommandComplete);
595
+ }
596
+ if (typeof this.sshObj.onCommandTimeout === 'function') {
597
+ this.removeListener("commandTimeout", this.sshObj.onCommandTimeout);
598
+ }
599
+ if (typeof this.sshObj.msg === 'function') {
600
+ this.removeListener("msg", this.sshObj.msg);
601
+ }
584
602
  if (this.idleTimer) {
585
603
  clearTimeout(this.idleTimer);
586
604
  }
@@ -594,7 +612,7 @@
594
612
  this.connect = bind(this.connect, this);
595
613
  this._loadDefaults = bind(this._loadDefaults, this);
596
614
  this._initiate = bind(this._initiate, this);
597
- this._removeEvents = bind(this._removeEvents, this);
615
+ this._removeListeners = bind(this._removeListeners, this);
598
616
  this.close = bind(this.close, this);
599
617
  this._runExit = bind(this._runExit, this);
600
618
  this._sshConnect = bind(this._sshConnect, this);
@@ -623,6 +641,11 @@
623
641
  this._hosts = [hosts];
624
642
  }
625
643
  this.ssh2Client = require('ssh2').Client;
644
+ this.on("msg", (function(_this) {
645
+ return function(message) {
646
+ return console.log(message);
647
+ };
648
+ })(this));
626
649
  this.on("newPrimmaryHost", this._nextPrimaryHost);
627
650
  this.on("data", (function(_this) {
628
651
  return function(data) {
@@ -684,8 +707,12 @@
684
707
  SSH2Shell.prototype._loadDefaults = function() {
685
708
  var ref, ref1, ref2, ref3, ref4, ref5, ref6;
686
709
  if (this.sshObj.msg && this.sshObj.msg.send && typeof this.sshObj.msg.send === 'function') {
687
- this.on("msg", this.sshObj.msg.send);
688
- } else if (this.sshObj.msg && typeof this.sshObj.msg === 'function') {
710
+ this.sshObj.msg = this.sshObj.msg.send;
711
+ }
712
+ if (this.listenerCount("msg") > 0) {
713
+ this.removeAllListeners("msg");
714
+ }
715
+ if (typeof this.sshObj.msg === 'function') {
689
716
  this.on("msg", this.sshObj.msg);
690
717
  } else {
691
718
  this.on("msg", (function(_this) {
@@ -831,7 +858,7 @@
831
858
  if (typeof this.sshObj.onEnd === 'function') {
832
859
  this.on("end", this.sshObj.onEnd);
833
860
  }
834
- if (this.sshObj.verbose) {
861
+ if (this.sshObj.debug) {
835
862
  this.emit('msg', this.sshObj.server.host + ": Host loaded");
836
863
  }
837
864
  if (this.sshObj.verbose) {
@@ -913,9 +940,8 @@
913
940
  _this._primaryhostSessionText += _this.sshObj.sessionText + "\n";
914
941
  _this._allSessions += _this._primaryhostSessionText;
915
942
  if (_this._hosts.length === 0) {
916
- _this.emit('end', _this._allSessions, _this.sshObj);
943
+ return _this.emit('end', _this._allSessions, _this.sshObj);
917
944
  }
918
- return _this._removeEvents();
919
945
  });
920
946
  return _this._stream.on("close", function(code, signal) {
921
947
  if (_this.sshObj.debug) {
@@ -952,7 +978,8 @@
952
978
  }
953
979
  if (_this._hosts.length === 0) {
954
980
  if (typeof _this._callback === 'function') {
955
- return _this._callback(_this._allSessions);
981
+ _this._callback(_this._allSessions);
982
+ return _this._removeListeners();
956
983
  }
957
984
  } else {
958
985
  return _this.emit("newPrimaryHost", _this._nextPrimaryHost(_this._connect));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ssh2shell",
3
- "version": "2.0.3",
3
+ "version": "2.0.6",
4
4
  "author": "cmp-202",
5
5
  "description": "A wrapper class for ssh2 to run multiple sequential commands in an SSH shell session, handle command responses, and tunnel through to other hosts using nested host objects",
6
6
  "main": "./lib/ssh2shell.js",
package/second.log ADDED
@@ -0,0 +1,30 @@
1
+ Welcome to Ubuntu 18.04.1 LTS (GNU/Linux 4.15.0-191-generic x86_64)
2
+
3
+ * Documentation: https://help.ubuntu.com
4
+ * Management: https://landscape.canonical.com
5
+ * Support: https://ubuntu.com/advantage
6
+
7
+ System information as of Wed Aug 17 20:13:26 NZST 2022
8
+
9
+ System load: 0.29 Processes: 100
10
+ Usage of /: 63.3% of 6.28GB Users logged in: 0
11
+ Memory usage: 5% IP address for enp0s3: 192.168.0.117
12
+ Swap usage: 0%
13
+
14
+ * Super-optimized for small spaces - read how we shrank the memory
15
+ footprint of MicroK8s to make it the smallest full K8s around.
16
+
17
+ https://ubuntu.com/blog/microk8s-memory-optimisation
18
+
19
+ 130 packages can be updated.
20
+ 3 updates are security updates.
21
+
22
+ New release '20.04.4 LTS' available.
23
+ Run 'do-release-upgrade' to upgrade to it.
24
+
25
+
26
+ banner content
27
+ Last login: Wed Aug 17 20:13:10 2022 from 192.168.0.6
28
+ user@ubuntu:~$ echo host pipe
29
+ host pipe
30
+ user@ubuntu:~$
@@ -284,7 +284,7 @@ class SSH2Shell extends Stream
284
284
  @.emit 'msg', "#{@sshObj.server.host}: SSH to #{nextHost.server.host}" if @sshObj.debug
285
285
  @.emit 'msg', "#{@sshObj.server.host}: Clearing previous event handlers" if @sshObj.debug
286
286
  @.emit 'msg', "#{@sshObj.server.host}: Remove previous event handlers" if @sshObj.debug
287
- @_removeEvents()
287
+ @_removeListeners()
288
288
 
289
289
  @_connections.push(@sshObj)
290
290
 
@@ -294,16 +294,17 @@ class SSH2Shell extends Stream
294
294
 
295
295
 
296
296
  _nextPrimaryHost: ( connect )=>
297
-
298
297
  if @_hosts.length > 0
299
- if @sshObj.server
298
+ #check this is not loading the first primary host before removing listeners
299
+ if @sshObj.server
300
300
  @.emit 'msg', "#{@sshObj.server.host}: Current primary host" if @sshObj.debug
301
301
  @.emit 'msg', "#{@sshObj.server.host}: Remove previous event handlers" if @sshObj.debug
302
- @_removeEvents()
303
- @sshObj = @_hosts.shift()
304
- @_primaryhostSessionText = "#{@sshObj.server.host}: "
302
+ @.emit 'end', @_primaryhostSessionText, @sshObj
303
+ @_removeListeners()
304
+ @sshObj = @_hosts.shift()
305
+ @_primaryhostSessionText = "#{@sshObj.server.host}: "
305
306
 
306
- @.emit 'msg', "#{@sshObj.server.host}: Next primary host" if @sshObj.debug
307
+ @.emit 'msg', "#{@sshObj.server.host}: Next primary host" if @sshObj.debug
307
308
 
308
309
  @_initiate(connect)
309
310
  else
@@ -369,7 +370,7 @@ class SSH2Shell extends Stream
369
370
  @.emit 'msg', "#{@sshObj.server.host}: Exit command: Stream: close" if @sshObj.debug
370
371
  @_stream.close() #"exit#{@sshObj.enter}"
371
372
 
372
- _removeEvents: =>
373
+ _removeListeners: =>
373
374
  ###
374
375
  if @sshObj.debug
375
376
  @.emit 'msg', "#{@sshObj.server.host}: Event handler count:"
@@ -383,15 +384,17 @@ class SSH2Shell extends Stream
383
384
  @.emit 'msg', "commandTimeout: " + (@.listenerCount 'commandTimeout')
384
385
  @.emit 'msg', "msg: " + (@.listenerCount 'msg')
385
386
  ###
387
+ #changed to removing host defined listeners instead of all listeners
388
+ @.removeListener "keyboard-interactive", @sshObj.onKeyboardInteractive if typeof @sshObj.onKeyboardInteractive == 'function'
389
+ @.removeListener "stderrData", @sshObj.onStderrData if typeof @sshObj.onStderrData == 'function'
386
390
  @.removeListener "data", @sshObj.onData if typeof @sshObj.onData == 'function'
387
- @.removeAllListeners "error"
391
+ @.removeListener "error", @sshObj.onError if typeof @sshObj.onError == 'function'
388
392
  @.removeListener "stderrData", @sshObj.onStderrData if typeof @sshObj.onStderrData == 'function'
389
- @.removeAllListeners 'end'
390
- @.removeAllListeners 'keyboard-interactive'
391
- @.removeAllListeners 'commandProcessing'
392
- @.removeAllListeners 'commandComplete'
393
- @.removeAllListeners 'commandTimeout'
394
- @.removeAllListeners 'msg'
393
+ @.removeListener "end", @sshObj.onEnd if typeof @sshObj.onEnd == 'function'
394
+ @.removeListener "commandProcessing", @sshObj.onCommandProcessing if typeof @sshObj.onCommandProcessing == 'function'
395
+ @.removeListener "commandComplete", @sshObj.onCommandComplete if typeof @sshObj.onCommandComplete == 'function'
396
+ @.removeListener "commandTimeout", @sshObj.onCommandTimeout if typeof @sshObj.onCommandTimeout == 'function'
397
+ @.removeListener "msg", @sshObj.msg if typeof @sshObj.msg == 'function'
395
398
 
396
399
  clearTimeout @idleTimer if @idleTimer
397
400
  clearTimeout @dataReceivedTimer if @dataReceivedTimer
@@ -402,15 +405,20 @@ class SSH2Shell extends Stream
402
405
  @_hosts = hosts
403
406
  else
404
407
  @_hosts = [hosts]
408
+
405
409
  @ssh2Client = require('ssh2').Client
406
410
 
411
+ #defined here to support msg events before the host is loaded
412
+ @.on "msg", ( message ) =>
413
+ console.log message
414
+
407
415
  @.on "newPrimmaryHost", @_nextPrimaryHost
408
416
 
409
- @.on "data", (data) =>
417
+ @.on "data", (data) =>
410
418
  @_onData( data )
411
419
 
412
420
  @.on "stderrData", (data) =>
413
- console.error data
421
+ console.error data
414
422
 
415
423
  @.on "error", (err, type, close = false, callback) =>
416
424
  @.emit 'msg', "Class.error: #{err}, #{type}" if @sshObj.debug
@@ -444,9 +452,14 @@ class SSH2Shell extends Stream
444
452
 
445
453
  _loadDefaults: () =>
446
454
 
455
+ #old hubot leftovers
447
456
  if @sshObj.msg and @sshObj.msg.send and typeof @sshObj.msg.send == 'function'
448
- @.on "msg", @sshObj.msg.send
449
- else if @sshObj.msg and typeof @sshObj.msg == 'function'
457
+ @sshObj.msg = @sshObj.msg.send
458
+
459
+ if @.listenerCount("msg") > 0
460
+ @.removeAllListeners "msg"
461
+
462
+ if typeof @sshObj.msg == 'function'
450
463
  @.on "msg", @sshObj.msg
451
464
  else
452
465
  @.on "msg", ( message ) =>
@@ -514,7 +527,7 @@ class SSH2Shell extends Stream
514
527
  @.on "commandTimeout", @sshObj.onCommandTimeout
515
528
  @.on "end", @sshObj.onEnd if typeof @sshObj.onEnd == 'function'
516
529
 
517
- @.emit 'msg', "#{@sshObj.server.host}: Host loaded" if @sshObj.verbose
530
+ @.emit 'msg', "#{@sshObj.server.host}: Host loaded" if @sshObj.debug
518
531
  @.emit 'msg', @sshObj if @sshObj.verbose
519
532
 
520
533
 
@@ -570,9 +583,7 @@ class SSH2Shell extends Stream
570
583
  @_primaryhostSessionText += @sshObj.sessionText+"\n"
571
584
  @_allSessions += @_primaryhostSessionText
572
585
  if @_hosts.length == 0
573
- @.emit 'end', @_allSessions, @sshObj
574
- @_removeEvents()
575
-
586
+ @.emit 'end', @_allSessions, @sshObj
576
587
 
577
588
  @_stream.on "close", (code, signal) =>
578
589
  @.emit 'msg', "#{@sshObj.server.host}: Stream.close" if @sshObj.debug
@@ -595,7 +606,8 @@ class SSH2Shell extends Stream
595
606
  if @_hosts.length == 0
596
607
  if typeof @_callback == 'function'
597
608
  @_callback @_allSessions
598
- else
609
+ @_removeListeners()
610
+ else
599
611
  @.emit "newPrimaryHost", @_nextPrimaryHost(@_connect)
600
612
 
601
613
 
package/test/.ignore DELETED
File without changes