Skip to content

Commit

Permalink
autossh (#69)
Browse files Browse the repository at this point in the history
  • Loading branch information
DumpySquare authored Sep 8, 2020
1 parent 869c167 commit 6ea0d48
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 44 deletions.
31 changes: 29 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,19 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how

---

## [2.3.0] - (9-4-2020)
## [2.3.0] - (9-8-2020)

### Added
- OUTPUT Logging
- Moved most console.log() information to the OUTPUT window at the bottom of the editor
- Channnel name is `f5-fast`
- Also reduced the amount of details for things like HTTP calls since much of that stuff can be seen with the expanded details of the editor details
- Clear password for single device
- onConnect/onDisconnect terminal command execution
- This provides the flexibility to have commands executed in the terminal at device connect/disconnect
- Examples shows terminal connecting to ssh and tailing ltm logs
- then disconnecting ssh when extension disconnects


### Added
- OUTPUT Logging
Expand All @@ -26,10 +38,25 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
- Tabs are now managed and re-used as configured
- Removed webviews and supporting packages
- Added the following settings:
- ******** document new settings *******
- `Http Response Details` provides http request/response header information (if any)
- `exchange` returns entire HTTP exchange including both request/response headers + body
- `full` returns response headers + body
- `body` returns response body only
- `New Editor Column` defines what column a new editor should be opened
- `current` use column of current active editor (focused)
- `beside` open editor in column beside currently active editor
- `New Editor Tab For All` provides a way for users to get a new tab for every response (how it originally worked)
- `Preserve Editor Focus` provides a way to keep the new editor tab from taking focus
- Updated axios agent to only return necessary information
- this also allowing for standardizing how responses are used across the entire extension
- Updated Device delete function to clear keytar password
- Added more documentation links to Examples view
- Vscode-f5-fast repo link to provide a quick way to access documentation, examples, and issues
- Fasting repo link to provide a quick way to clone repo for demo's
- AS3 User Guide link to provide a quick way to get users to ALL AS3 documentation
- This seemed better than providing a link for each of the necessary subsections
- Updated comment tags when hovering over each item
- Provided links to repos online for DO/TS at the parent level

---

Expand Down
16 changes: 14 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"displayName": "F5 Networks FAST",
"description": "(F)5 Networks (A)pplication (S)ervices (T)emplate engine extension",
"publisher": "DumpySquare",
"version": "2.2.0",
"version": "2.3.0",
"keywords": [
"f5",
"f5networks",
Expand Down Expand Up @@ -95,7 +95,7 @@
},
{
"id": "decExamples",
"name": "Declaration Examples"
"name": "Documentation/Examples"
}
]
},
Expand Down Expand Up @@ -129,6 +129,18 @@
"ldap",
"custom"
]
},
"onConnect": {
"type":"array",
"description": "List of terminal/bash commands to execute at connect",
"examples": [
"ssh [email protected]",
"ssh ${this.device}"
]
},
"onDisconnect": {
"type":"array",
"description": "List of terminal/bash commands to execute at disconnect"
}
},
"required": [
Expand Down
7 changes: 0 additions & 7 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1039,13 +1039,6 @@ export function activate(context: vscode.ExtensionContext) {

context.subscriptions.push(vscode.commands.registerCommand('f5.getGitHubExample', async (decUrl) => {

const gitIssueUrl = 'https://github.com/F5Networks/f5-appsvcs-extension/issues/280';

if(decUrl === 'tempAS3') {
// remove once as3 examples are available
return vscode.env.openExternal(vscode.Uri.parse(gitIssueUrl));
}

const resp = await extAPI.makeRequest({ url: decUrl });
return panel.render(resp);
}));
Expand Down
68 changes: 48 additions & 20 deletions src/treeViewsProviders/githubDecExamples.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import * as vscode from 'vscode';
import { TreeDataProvider, TreeItem, TreeItemCollapsibleState, Event, EventEmitter, Uri, Command } from 'vscode';
import { callHTTPS } from '../utils/externalAPIs';


export class ExampleDecsProvider implements vscode.TreeDataProvider<ExampleDec> {
dispose() {
throw new Error("Method not implemented.");
}
export class ExampleDecsProvider implements TreeDataProvider<ExampleDec> {

private _onDidChangeTreeData: vscode.EventEmitter<ExampleDec | undefined> = new vscode.EventEmitter<ExampleDec | undefined>();
readonly onDidChangeTreeData: vscode.Event<ExampleDec | undefined> = this._onDidChangeTreeData.event;
private _onDidChangeTreeData: EventEmitter<ExampleDec | undefined> = new EventEmitter<ExampleDec | undefined>();
readonly onDidChangeTreeData: Event<ExampleDec | undefined> = this._onDidChangeTreeData.event;

constructor() {
}
Expand All @@ -17,7 +14,7 @@ export class ExampleDecsProvider implements vscode.TreeDataProvider<ExampleDec>
this._onDidChangeTreeData.fire();
}

getTreeItem(element: ExampleDec): vscode.TreeItem {
getTreeItem(element: ExampleDec): TreeItem {
return element;
}

Expand All @@ -30,35 +27,61 @@ export class ExampleDecsProvider implements vscode.TreeDataProvider<ExampleDec>
// const examples = await getAS3examples();

// treeItems = examples.body.map((item: any) => {
// return new ExampleDec(item.name, vscode.TreeItemCollapsibleState.None,
// return new ExampleDec(item.name, TreeItemCollapsibleState.None,
// {command: 'f5.getGitHubExample', title: '', arguments: [item.download_url]});
// });

} else if (element.label === 'DO Examples') {
const examples = await getDOexamples();

treeItems = examples.body.map((item: any) => {
return new ExampleDec(item.name, vscode.TreeItemCollapsibleState.None,
return new ExampleDec(item.name, '', TreeItemCollapsibleState.None,
{command: 'f5.getGitHubExample', title: '', arguments: [item.download_url]});
});

} else if (element.label === 'TS Examples') {
const examples = await getTSexamples();

treeItems = examples.body.map((item: any) => {
return new ExampleDec(item.name, vscode.TreeItemCollapsibleState.None,
return new ExampleDec(item.name, '', TreeItemCollapsibleState.None,
{command: 'f5.getGitHubExample', title: '', arguments: [item.download_url]});
});
}

} else {
//top level items
treeItems.push(new ExampleDec('AS3 Examples - Coming soon!', vscode.TreeItemCollapsibleState.None,
{command: 'f5.getGitHubExample', title: '', arguments: ['tempAS3']}));

treeItems.push(new ExampleDec('DO Examples', vscode.TreeItemCollapsibleState.Collapsed));

treeItems.push(new ExampleDec('TS Examples', vscode.TreeItemCollapsibleState.Collapsed));
let link: Uri;
let comment: string;

link = Uri.parse('https://github.com/DumpySquare/vscode-f5-fast');
comment = 'Main vscode-f5-fast repo for documentation and issues';
treeItems.push(new ExampleDec('vscode-f5-fast repo', comment, TreeItemCollapsibleState.None,
{command: 'vscode.open', title: '', arguments: [link]}));

link = Uri.parse('https://github.com/DumpySquare/f5-fasting');
comment = 'Repo used to document usage and examples used in the extension';
treeItems.push(new ExampleDec('f5-fasting repo', comment, TreeItemCollapsibleState.None,
{command: 'vscode.open', title: '', arguments: [link]}));

link = Uri.parse('https://clouddocs.f5.com/products/extensions/f5-appsvcs-extension/latest/userguide/');
comment = 'Best way to get to all documentation official F5 CloudDocs documenation for as3, including: installing, using, HTTP methods, example declarations...';
treeItems.push(new ExampleDec('AS3 User Guide', comment, TreeItemCollapsibleState.None,
{command: 'vscode.open', title: '', arguments: [link]}));

link = Uri.parse('https://github.com/F5Networks/f5-appsvcs-extension/issues/280');
comment = 'Please comment in git repo if you want all AS3 example declarations to show up like DO/TS below';
treeItems.push(new ExampleDec('AS3 Examples - Coming soon!', comment, TreeItemCollapsibleState.None,
{command: 'vscode.open', title: '', arguments: [link]}));

link = Uri.parse('https://github.com/F5Networks/f5-declarative-onboarding/tree/master/examples');
comment = 'DO examples direct from /F5Networks/f5-declarative-onboarding repo';
treeItems.push(new ExampleDec('DO Examples', comment, TreeItemCollapsibleState.Collapsed,
{command: 'vscode.open', title: '', arguments: [link]}));

link = Uri.parse('https://github.com/F5Networks/f5-telemetry-streaming/tree/master/examples');
comment = 'TS examples direct from /F5Networks/f5-telemetry-streaming repo';
treeItems.push(new ExampleDec('TS Examples', comment, TreeItemCollapsibleState.Collapsed,
{command: 'vscode.open', title: '', arguments: [link]}));
}
return Promise.resolve(treeItems);
}
Expand Down Expand Up @@ -102,13 +125,18 @@ async function getTSexamples(){
});
}

export class ExampleDec extends vscode.TreeItem {
export class ExampleDec extends TreeItem {
constructor(
public readonly label: string,
// private version: string,
public readonly collapsibleState: vscode.TreeItemCollapsibleState,
public readonly command?: vscode.Command
private toolTip: string,
public readonly collapsibleState: TreeItemCollapsibleState,
public readonly command?: Command
) {
super(label, collapsibleState);
}

get tooltip(): string {
return this.toolTip;
}
}
2 changes: 1 addition & 1 deletion src/treeViewsProviders/hostsTreeProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export class F5TreeProvider implements vscode.TreeDataProvider<F5Host> {
async removeDevice(hostID: any) {
logger.debug(`Remove Host command: ${JSON.stringify(hostID)}`);

this.clearPassword(hostID.label);
this.clearPassword(hostID.label); // clear cached password for device

let bigipHosts: {device: string} [] | undefined = vscode.workspace.getConfiguration().get('f5.hosts');

Expand Down
84 changes: 72 additions & 12 deletions src/utils/f5DeviceClient.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
'use strict';

import * as vscode from 'vscode';
import { Terminal, window, workspace, ProgressLocation, StatusBarAlignment, commands } from 'vscode';
import { makeAuth, makeReqAXnew, multiPartUploadSDK } from './coreF5HTTPS';
import { ext, loadConfig } from '../extensionVariables';
import * as utils from './utils';
import logger from './logger';

export interface Device {
device: string,
provider?: string,
onConnect?: string[],
onDisconnect?: string[]
}

/**
*
* Basic Example:
Expand All @@ -30,7 +37,9 @@ export class MgmtClient {
protected _token: any;
protected _tmrBar: any;
protected _tokenTimeout: number = 0;

private _onConnect: string[] = [];
private _onDisconnect: string[] = [];
private terminal: Terminal;

/**
* @param options function options
Expand All @@ -50,6 +59,27 @@ export class MgmtClient {
this.provider = options['provider'];
this._user = options['user'];
this._password = options['password'];
this.getConfig();
this.terminal = window.createTerminal('f5-fast-cmd');
this.terminal.show(true);
}

/**
* Get vscode workspace configuration for this device
*/
private getConfig() {

this._onConnect = [];
this._onDisconnect = [];

const bigipHosts: Device[] | undefined = workspace.getConfiguration().get('f5.hosts');
const deviceConfig: any = bigipHosts?.find( item => item.device === this.device);

if (deviceConfig?.hasOwnProperty('onConnect')) {
this._onConnect = deviceConfig.onConnect;
} else if (deviceConfig?.hasOwnProperty('onDisconnect')) {
this._onConnect = deviceConfig.onDisconnect;
}
}


Expand Down Expand Up @@ -81,9 +111,9 @@ export class MgmtClient {
* Pulls device/connection details from this. within the class
*/
async connect() {
await this.disconnect();
const progress = await vscode.window.withProgress({
location: vscode.ProgressLocation.Notification,
// await this.disconnect();
const progress = await window.withProgress({
location: ProgressLocation.Notification,
title: `Connecting to ${this.host}`,
cancellable: true
}, async (progress, token) => {
Expand Down Expand Up @@ -166,6 +196,7 @@ export class MgmtClient {
}
return returnInfo;
});
this.termConnect();
return progress;
}

Expand Down Expand Up @@ -234,11 +265,11 @@ export class MgmtClient {
*/
private async tokenTimer() {

this._tmrBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 50);
this._tmrBar = window.createStatusBarItem(StatusBarAlignment.Left, 50);
this._tmrBar.tooltip = 'F5 AuthToken Timer';
this._tmrBar.color = 'silver';

const makeVisible = vscode.workspace.getConfiguration().get('f5.showAuthTokenTimer');
const makeVisible = workspace.getConfiguration().get('f5.showAuthTokenTimer');
if(makeVisible) {
this._tmrBar.show();
}
Expand All @@ -265,7 +296,7 @@ export class MgmtClient {


/**
* clears auth token and connected status bars
* clears auth token, connected status bars, and onDisconnect commands
*/
async disconnect() {

Expand All @@ -286,21 +317,50 @@ export class MgmtClient {
* next connect should refresh the data as needed, but there seems to
* be a better way to do this.
*/
vscode.commands.executeCommand('setContext', 'f5.tcl', false);
commands.executeCommand('setContext', 'f5.tcl', false);
// ext.iRulesAble = false;

// show connect status bar
ext.connectBar.show();
ext.connectBar.show();

this.termDisConnect();
}


/**
* clears password for currently connected device
* to be called by http since it won't know curren
* to be called by http since it won't know current
* device details
*/
async clearPassword() {
await vscode.commands.executeCommand('f5.clearPassword', { label: this.device });
await commands.executeCommand('f5.clearPassword', { label: this.device });
}

/**
* issues terminal commands defined for "onConnect"
*/
private termConnect() {
// if _onConnect has a value, loop through each as terminal commands
this._onConnect?.forEach((el: string) => {
// swap out variable as needed
el = el.replace(/\${this.device}/, `${this.device}`);
setTimeout( () => {
// console.log(el);
this.terminal.sendText(el);
}, 500);
});
}

/**
* issue terminal commands defined for "onDisonnect"
*/
private termDisConnect() {
// if _onDisconnect has a value, loop through each as terminal commands
this._onDisconnect?.forEach((el: string) => {
setTimeout( () => {
this.terminal.sendText(el);
}, 500);
});
}

}
Expand Down

0 comments on commit 6ea0d48

Please sign in to comment.