Skip to content

Commit

Permalink
NodeExplorer: Implements Nodes list (#106)
Browse files Browse the repository at this point in the history
This is the start of a Node Explorer, hidden behind a setting.

---------

Signed-off-by: Tyler Smalley <tyler@tailscale.com>
Co-authored-by: Marwan Sulaiman <marwan.sameer@gmail.com>
  • Loading branch information
tylersmalley and marwan-at-work committed Jul 18, 2023
1 parent d1e0ef1 commit 327cc09
Show file tree
Hide file tree
Showing 14 changed files with 721 additions and 4 deletions.
8 changes: 8 additions & 0 deletions node-explorer-TODO.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
* Handle offline, or unavailable - show error
* Add refresh action
* change user (node context)
* change root directory (node and FileExplorer context)
* figure out why the progress bar doesn't show up
* add file explorer context (get path, delete, rename)
* download button
*
59 changes: 58 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,29 @@
{
"command": "tailscale.openAdminConsole",
"group": "overflow",
"when": "view == tailscale-serve-view"
"when": "view == tailscale-serve-view || view == tailscale-node-explorer-view"
}
],
"view/item/context": [
{
"command": "tailscale.copyIPv4",
"when": "view == tailscale-node-explorer-view && viewItem == tailscale-peer-item",
"group": "1_peer@1"
},
{
"command": "tailscale.copyIPv6",
"when": "view == tailscale-node-explorer-view && viewItem == tailscale-peer-item",
"group": "1_peer@1"
},
{
"command": "tailscale.copyHostname",
"when": "view == tailscale-node-explorer-view && viewItem == tailscale-peer-item",
"group": "1_peer@1"
},
{
"command": "tailscale.ssh.delete",
"group": "fileActions@2",
"when": "view == tailscale-node-explorer-view && viewItem == file-explorer-item"
}
]
},
Expand Down Expand Up @@ -164,6 +186,22 @@
"command": "tailscale.simpleServeView",
"title": "Simple View",
"category": "tsdev"
},
{
"command": "tailscale.copyIPv4",
"title": "Copy IPv4"
},
{
"command": "tailscale.copyIPv6",
"title": "Copy IPv6"
},
{
"command": "tailscale.copyHostname",
"title": "Copy Hostname"
},
{
"command": "tailscale.ssh.delete",
"title": "Delete"
}
],
"viewsContainers": {
Expand All @@ -173,6 +211,13 @@
"title": "Tailscale",
"icon": "images/tailscale.svg"
}
],
"activitybar": [
{
"icon": "resources/images/mark.svg",
"id": "tailscale-nodes-explorer",
"title": "Tailscale"
}
]
},
"views": {
Expand All @@ -182,6 +227,13 @@
"name": "Funnel",
"type": "webview"
}
],
"tailscale-nodes-explorer": [
{
"id": "tailscale-node-explorer-view",
"name": "Nodes",
"when": "config.tailscale.nodeExplorer.enabled"
}
]
},
"configuration": [
Expand All @@ -207,6 +259,11 @@
"examples": [
false
]
},
"tailscale.nodeExplorer.enabled": {
"type": "boolean",
"default": false,
"markdownDescription": "(IN DEVELOPMENT) Enable the Tailscale Node Explorer view."
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions resources/dark/offline.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions resources/dark/online.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/dark/terminal.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions resources/images/mark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions resources/light/offline.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions resources/light/online.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/light/terminal.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 54 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ import { ADMIN_CONSOLE } from './utils/url';
import { Tailscale } from './tailscale';
import { Logger } from './logger';
import { errorForType } from './tailscale/error';
import {
FileExplorer,
NodeExplorerProvider,
PeerDetailTreeItem,
PeerTree,
} from './node-explorer-provider';

import { TSFileSystemProvider } from './ts-file-system-provider';

let tailscaleInstance: Tailscale;

Expand Down Expand Up @@ -45,6 +53,22 @@ export async function activate(context: vscode.ExtensionContext) {
tailscaleInstance
);

const tsObjFileSystemProvider = new TSFileSystemProvider();
context.subscriptions.push(
vscode.workspace.registerFileSystemProvider('ts', tsObjFileSystemProvider, {
isCaseSensitive: true,
})
);

const nodeExplorerProvider = new NodeExplorerProvider(tailscaleInstance);
vscode.window.registerTreeDataProvider('tailscale-node-explorer-view', nodeExplorerProvider);
const view = vscode.window.createTreeView('tailscale-node-explorer-view', {
treeDataProvider: nodeExplorerProvider,
showCollapseAll: true,
dragAndDropController: nodeExplorerProvider,
});
context.subscriptions.push(view);

context.subscriptions.push(
vscode.commands.registerCommand('tailscale.refreshServe', () => {
Logger.info('called tailscale.refreshServe', 'command');
Expand Down Expand Up @@ -74,6 +98,36 @@ export async function activate(context: vscode.ExtensionContext) {
})
);

context.subscriptions.push(
vscode.commands.registerCommand('tailscale.copyIPv4', async (node: PeerTree) => {
const ip = node.TailscaleIPs[0];

if (!ip) {
vscode.window.showErrorMessage(`No IPv4 address found for ${node.HostName}.`);
return;
}

await vscode.env.clipboard.writeText(ip);
vscode.window.showInformationMessage(`Copied ${ip} to clipboard.`);
})
);

context.subscriptions.push(
vscode.commands.registerCommand('tailscale.copyIPv6', async (node: PeerTree) => {
const ip = node.TailscaleIPs[1];
await vscode.env.clipboard.writeText(ip);
vscode.window.showInformationMessage(`Copied ${ip} to clipboard.`);
})
);

context.subscriptions.push(
vscode.commands.registerCommand('tailscale.copyHostname', async (node: PeerTree) => {
const name = node.HostName;
await vscode.env.clipboard.writeText(name);
vscode.window.showInformationMessage(`Copied ${name} to clipboard.`);
})
);

vscode.window.registerWebviewViewProvider('tailscale-serve-view', servePanelProvider);

context.subscriptions.push(
Expand Down
Loading

0 comments on commit 327cc09

Please sign in to comment.