diff --git a/terminus-ssh/src/api.ts b/terminus-ssh/src/api.ts index 5edb4ea6..85f9cd46 100644 --- a/terminus-ssh/src/api.ts +++ b/terminus-ssh/src/api.ts @@ -1,5 +1,10 @@ import { BaseSession } from 'terminus-terminal' +export interface LoginScript { + expect?: string + send: string +} + export interface SSHConnection { name?: string host: string @@ -7,18 +12,43 @@ export interface SSHConnection { user: string password?: string privateKey?: string + scripts?: LoginScript[] } export class SSHSession extends BaseSession { - constructor (private shell: any) { + scripts?: LoginScript[] + + constructor (private shell: any, conn: SSHConnection) { super() + this.scripts = conn.scripts.slice(0); } start () { this.open = true this.shell.on('data', data => { - this.emitOutput(data.toString()) + let dataString = data.toString() + this.emitOutput(dataString) + + if (this.scripts && this.scripts.length > 0) { + let found = false + for (let i = 0; i < this.scripts.length; i++) { + if (dataString.indexOf(this.scripts[i].expect) >= 0) { + console.log("Executing: " + this.scripts[i].send) + this.shell.write(this.scripts[i].send + "\n") + this.scripts.splice(i, 1) + i-- + found = true + } + else { + break; + } + } + + if (found) { + this.executeScripts() + } + } }) this.shell.on('end', () => { @@ -26,6 +56,24 @@ export class SSHSession extends BaseSession { this.destroy() } }) + + this.executeScripts() + } + + executeScripts () { + if (this.scripts && this.scripts.length > 0) { + for (let i = 0; i < this.scripts.length; i++) { + if (!this.scripts[i].expect) { + console.log("Executing: " + this.scripts[i].send) + this.shell.write(this.scripts[i].send + "\n") + this.scripts.splice(i, 1) + i-- + } + else { + break; + } + } + } } resize (columns, rows) { diff --git a/terminus-ssh/src/components/editConnectionModal.component.pug b/terminus-ssh/src/components/editConnectionModal.component.pug index 006e7563..9fdbad7a 100644 --- a/terminus-ssh/src/components/editConnectionModal.component.pug +++ b/terminus-ssh/src/components/editConnectionModal.component.pug @@ -1,45 +1,101 @@ .modal-body - .form-group - label Name - input.form-control( - type='text', - [(ngModel)]='connection.name', - ) + ngb-tabset(type='pills', [activeId]='basic') + ngb-tab(id='basic') + ng-template(ngbTabTitle) + | Basic Setting + ng-template(ngbTabContent) + h4 Basic Setting + .form-group + label Name + input.form-control( + type='text', + [(ngModel)]='connection.name', + ) - .form-group - label Host - input.form-control( - type='text', - [(ngModel)]='connection.host', - ) + .form-group + label Host + input.form-control( + type='text', + [(ngModel)]='connection.host', + ) - .form-group - label Port - input.form-control( - type='number', - placeholder='22', - [(ngModel)]='connection.port', - ) + .form-group + label Port + input.form-control( + type='number', + placeholder='22', + [(ngModel)]='connection.port', + ) - .form-group - label Username - input.form-control( - type='text', - [(ngModel)]='connection.user', - ) + .form-group + label Username + input.form-control( + type='text', + [(ngModel)]='connection.user', + ) - .form-group - label Private key - .input-group - input.form-control( - type='text', - placeholder='Key file path', - [(ngModel)]='connection.privateKey' - ) - .input-group-btn - button.btn.btn-secondary((click)='selectPrivateKey()') - i.fa.fa-folder-open + .form-group + label Private key + .input-group + input.form-control( + type='text', + placeholder='Key file path', + [(ngModel)]='connection.privateKey' + ) + .input-group-btn + button.btn.btn-secondary((click)='selectPrivateKey()') + i.fa.fa-folder-open + ngb-tab(id='scripts') + ng-template(ngbTabTitle) + | Login Scripts + ng-template(ngbTabContent) + h4 Login Scripts + .list-group + table + tr + th String to wait + th String to be sent + th Actions + tr(*ngFor='let script of connection.scripts') + td + input.form-control( + type='text', + value='{{script.expect}}', + ) + td + input.form-control( + type='text', + value='{{script.send}}', + ) + td + .input-group.flex-nowrap + button.btn.btn-outline-info.ml-0((click)='up(script)') + i.fa.fa-arrow-up + button.btn.btn-outline-info.ml-0((click)='down(script)') + i.fa.fa-arrow-down + button.btn.btn-outline-danger.ml-0((click)='delete(script)') + i.fa.fa-trash-o + tr + td + input.form-control( + type='text', + placeholder='Enter a string to wait', + [(ngModel)]='newScript.expect' + ) + td + input.form-control( + type='text', + placeholder='Enter a string to be sent', + [(ngModel)]='newScript.send' + ) + td + .input-group.flex-nowrap + button.btn.btn-outline-info.ml-0((click)='add()') + i.fa.fa-save + button.btn.btn-outline-danger.ml-0((click)='clear()') + i.fa.fa-trash-o + .modal-footer button.btn.btn-outline-primary((click)='save()') Save button.btn.btn-outline-danger((click)='cancel()') Cancel diff --git a/terminus-ssh/src/components/editConnectionModal.component.ts b/terminus-ssh/src/components/editConnectionModal.component.ts index 62dd3eb1..d33b3053 100644 --- a/terminus-ssh/src/components/editConnectionModal.component.ts +++ b/terminus-ssh/src/components/editConnectionModal.component.ts @@ -1,19 +1,22 @@ import { Component } from '@angular/core' import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap' import { ElectronService, HostAppService } from 'terminus-core' -import { SSHConnection } from '../api' +import { SSHConnection, LoginScript } from '../api' @Component({ template: require('./editConnectionModal.component.pug'), }) export class EditConnectionModalComponent { connection: SSHConnection + newScript: LoginScript constructor ( private modalInstance: NgbActiveModal, private electron: ElectronService, private hostApp: HostAppService, - ) { } + ) { + this.newScript = { expect: "", send: ""} + } selectPrivateKey () { let path = this.electron.dialog.showOpenDialog( @@ -34,4 +37,38 @@ export class EditConnectionModalComponent { cancel () { this.modalInstance.dismiss() } + + up (script: LoginScript) { + let index = this.connection.scripts.indexOf(script) + if (index > 0) { + this.connection.scripts.splice(index, 1); + this.connection.scripts.splice(index - 1, 0, script); + } + } + + down (script: LoginScript) { + let index = this.connection.scripts.indexOf(script) + if (index >= 0 && index < this.connection.scripts.length - 1) { + this.connection.scripts.splice(index, 1); + this.connection.scripts.splice(index + 1, 0, script); + } + } + + delete (script: LoginScript) { + if (confirm(`Delete?`)) { + this.connection.scripts = this.connection.scripts.filter(x => x !== script) + } + } + + add () { + if (!this.connection.scripts) + this.connection.scripts = [] + this.connection.scripts.push(Object.assign({}, this.newScript)) + this.clear(); + } + + clear () { + this.newScript.expect = "" + this.newScript.send = "" + } } diff --git a/terminus-ssh/src/components/sshSettingsTab.component.ts b/terminus-ssh/src/components/sshSettingsTab.component.ts index 020f6a9a..2e13d0dd 100644 --- a/terminus-ssh/src/components/sshSettingsTab.component.ts +++ b/terminus-ssh/src/components/sshSettingsTab.component.ts @@ -24,6 +24,7 @@ export class SSHSettingsTabComponent { port: 22, user: 'root', } + let modal = this.ngbModal.open(EditConnectionModalComponent) modal.componentInstance.connection = connection modal.result.then(result => { diff --git a/terminus-ssh/src/services/ssh.service.ts b/terminus-ssh/src/services/ssh.service.ts index 04aae782..afebc65a 100644 --- a/terminus-ssh/src/services/ssh.service.ts +++ b/terminus-ssh/src/services/ssh.service.ts @@ -148,7 +148,7 @@ export class SSHService { }) }) - let session = new SSHSession(shell) + let session = new SSHSession(shell, connection) return this.zone.run(() => this.app.openNewTab( TerminalTabComponent,