-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathdeviceImport.ts
222 lines (173 loc) · 6.38 KB
/
deviceImport.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
import * as fs from 'fs';
import * as path from 'path';
import { ConfigurationTarget, window, workspace } from 'vscode';
import { ext } from './extensionVariables';
import { F5TreeProvider } from './treeViewsProviders/hostsTreeProvider';
import { isValidJson } from './utils/utils';
import { logger } from './logger';
/**
* Looks for device seed file based on path
* if found, prompt user to import
* @param path of extension core dir
*/
export async function deviceImportOnLoad(extPath: string, hostsTreeProvider: F5TreeProvider) {
let seedContent: string = '';
try {
// try to find/read the seed file
seedContent = fs.readFileSync(path.join(extPath, '.vscode-f5.json'), 'utf-8');
logger.debug('device seed file detected');
/**
* can also look into searching a workspace if there is one at start up
*/
} catch (e) {
// 2.7.2021 -> disabled this log message since it was causing confusion
// return logger.debug('device seed file not found', e.message);
return;
}
const q = await window.showInformationMessage('Device seed file detected, would you like to import?', 'Yes', 'Yes-Consume', 'No');
// const y = await window.showInformationMessage('found device import file', );
if (q === 'Yes' && seedContent) {
// read seed file
// pass to, call deviceImport
await deviceImport(seedContent);
} else if (q === 'Yes-Consume' && seedContent) {
// read seed file -> import
await deviceImport(seedContent);
// user selected consume -> delete file
setTimeout( () => {
logger.debug('Deleting seed file at', path.join(extPath, '.vscode-f5.json'));
fs.unlinkSync(path.join(extPath, '.vscode-f5.json'));
}, 2000);
} else if (q === 'No' || q === undefined) {
logger.debug('device seed import declined by user');
}
// Refresh hosts tree to show new devices
setTimeout( () => { hostsTreeProvider.refresh();}, 1000);
}
type CfgDevice = {
device: string,
password?: string,
provider?: string
};
/**
* imports device list to user config file
*
* acceptable inputs as strings:
* - '[email protected]'
* - ['[email protected]', '[email protected]:8443', ...]
* - [{ device: '[email protected]', password: 'pizzaTower', provider: 'tmos' }, ...]
*
* @param seed file as a string
*/
export async function deviceImport(seed: string) {
// converts the different input structurs to a standard object list
const seedList2 = await parseDeviceLoad(seed);
// todo/bug: Import Devices only takes one device at a time #248
await seedList2.forEach(async (el: CfgDevice) => {
await addDevice(el);
});
// outputKeytar();
return;
}
/**
* converts seed file to standard format for importing
* acceptable inputs:
* - '[email protected]'
* - ['[email protected]', '[email protected]:8443', ...]
* - [{ device: '[email protected]', password: 'pizzaTower', provider: 'tmos' }, ...]
* - { device: '[email protected]', password: 'pizzaTower', provider: 'tmos' }
*
* had to wrap in a function to provde a standard typed output
*
* @param seed file as a string
*/
export async function parseDeviceLoad (seed: string) {
// trim any leading and trailing spaces
seed = seed.trim();
const seedList = isValidJson(seed);
// if seedlist is a single object, convert to array
if (seedList && typeof seedList === 'object' && !Array.isArray(seedList)) {
return [seedList];
} else
if (seedList) {
return seedList.map( (el: string | CfgDevice) => {
if (typeof el === 'string') {
// convert single string
return { device: el };
} else {
// should be an object in the format we already need
return el;
}
});
} else {
logger.info('failed to parse seed as JSON - returning single device as string');
return [{ device: seed }];
}
}
/**
* Adds device to config
* @param device
*/
async function addDevice (device: {device: string, provider?: string, password?: string}) {
let bigipHosts: {device: string} [] | undefined = await workspace.getConfiguration().get('f5.hosts');
if (bigipHosts === undefined) {
// throw new Error('no devices in config?');
bigipHosts = [];
}
// the following is a quick and dirty way to search the entire
// devices config obj for a match without having to check each piece
const deviceRex = /^[\w-.]+@[\w-.]+(:[0-9]+)?$/; // matches any username combo an F5 will accept and host/ip
const devicesString = JSON.stringify(bigipHosts);
let password = '';
if (device.password) {
// extract password from object
password = device.password;
delete device.password;
}
if (!devicesString.includes(`\"${device.device}\"`) && deviceRex.test(device.device)){
bigipHosts.push(device);
await workspace.getConfiguration().update('f5.hosts', bigipHosts, ConfigurationTarget.Global);
if (password) {
// inject password to cache
await importPassword(device.device, password);
logger.debug(`password added for ${device.device}`);
}
logger.debug(`${device.device} added to device configuration`);
return;
} else {
logger.debug('device import failed on', device.device);
return;
}
}
async function importPassword (device: string, password: string) {
// return await ext.keyTar.setPassword('f5Hosts', device, password);
return await ext.context.secrets.store(device, password);
}
// /**
// * following is only used for troubleshooting...
// */
// async function outputKeytar () {
// ext.keyTar.findCredentials('f5Hosts').then( list => {
// // map through and delete all
// list.map(item => {
// const psswd = ext.keyTar.getPassword('f5Hosts', item.account);
// // console.log('***KEYTAR OUTPUT***', JSON.stringify(item));
// });
// });
// }
export const exampleImport = {
devices: [
{
device: '[email protected]:8443'
},
{
device: '[email protected]',
password: 'giraffie'
},
{
device: '[email protected]',
password: 'coolness',
provider: 'tmos'
}
]
};