@kumologica/sdk 3.0.0-alpha4

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.
Files changed (76) hide show
  1. package/README.md +52 -0
  2. package/bin/kl.js +2 -0
  3. package/cli/KumologicaError.js +17 -0
  4. package/cli/cli.js +7 -0
  5. package/cli/commands/build-commands/aws.js +49 -0
  6. package/cli/commands/build-commands/azure.js +43 -0
  7. package/cli/commands/build-commands/kumohub.js +49 -0
  8. package/cli/commands/build.js +6 -0
  9. package/cli/commands/create-commands/create-project-iteratively.js +49 -0
  10. package/cli/commands/create-commands/index.js +5 -0
  11. package/cli/commands/create.js +66 -0
  12. package/cli/commands/deploy-commands/kumohub.js +114 -0
  13. package/cli/commands/deploy.js +6 -0
  14. package/cli/commands/doc-commands/html.js +60 -0
  15. package/cli/commands/doc.js +6 -0
  16. package/cli/commands/export-commands/cloudformation.js +371 -0
  17. package/cli/commands/export-commands/serverless.js +164 -0
  18. package/cli/commands/export-commands/terraform-commands/aws.js +193 -0
  19. package/cli/commands/export-commands/terraform-commands/azure.js +148 -0
  20. package/cli/commands/export-commands/terraform.js +6 -0
  21. package/cli/commands/export-commands/utils/validator.js +195 -0
  22. package/cli/commands/export.js +6 -0
  23. package/cli/commands/list-templates.js +24 -0
  24. package/cli/commands/open.js +53 -0
  25. package/cli/commands/start.js +165 -0
  26. package/cli/commands/test/TestSuiteRunner.js +76 -0
  27. package/cli/commands/test.js +123 -0
  28. package/cli/utils/download-template-from-repo.js +346 -0
  29. package/cli/utils/download-test.js +12 -0
  30. package/cli/utils/download.js +119 -0
  31. package/cli/utils/fs/copy-dir-contents-sync.js +15 -0
  32. package/cli/utils/fs/create-zip-file.js +39 -0
  33. package/cli/utils/fs/dir-exists-sync.js +14 -0
  34. package/cli/utils/fs/dir-exists.js +17 -0
  35. package/cli/utils/fs/file-exists-sync.js +14 -0
  36. package/cli/utils/fs/file-exists.js +12 -0
  37. package/cli/utils/fs/get-tmp-dir-path.js +22 -0
  38. package/cli/utils/fs/parse.js +40 -0
  39. package/cli/utils/fs/read-file-sync.js +11 -0
  40. package/cli/utils/fs/read-file.js +10 -0
  41. package/cli/utils/fs/safe-move-file.js +58 -0
  42. package/cli/utils/fs/walk-dir-sync.js +34 -0
  43. package/cli/utils/fs/write-file-sync.js +31 -0
  44. package/cli/utils/fs/write-file.js +32 -0
  45. package/cli/utils/logger.js +26 -0
  46. package/cli/utils/rename-service.js +49 -0
  47. package/package.json +72 -0
  48. package/src/api/core/comms.js +141 -0
  49. package/src/api/core/context.js +296 -0
  50. package/src/api/core/flows.js +286 -0
  51. package/src/api/core/index.js +29 -0
  52. package/src/api/core/library.js +106 -0
  53. package/src/api/core/nodes.js +476 -0
  54. package/src/api/core/projects.js +426 -0
  55. package/src/api/core/rest/context.js +42 -0
  56. package/src/api/core/rest/flow.js +53 -0
  57. package/src/api/core/rest/flows.js +53 -0
  58. package/src/api/core/rest/index.js +171 -0
  59. package/src/api/core/rest/nodes.js +164 -0
  60. package/src/api/core/rest/util.js +53 -0
  61. package/src/api/core/settings.js +287 -0
  62. package/src/api/tools/base/DesignerTool.js +108 -0
  63. package/src/api/tools/core/flow.js +58 -0
  64. package/src/api/tools/core/index.js +18 -0
  65. package/src/api/tools/core/node.js +77 -0
  66. package/src/api/tools/debugger/index.js +193 -0
  67. package/src/api/tools/filemanager/index.js +127 -0
  68. package/src/api/tools/git/index.js +103 -0
  69. package/src/api/tools/index.js +13 -0
  70. package/src/api/tools/test/index.js +56 -0
  71. package/src/api/tools/test/lib/TestCaseRunner.js +105 -0
  72. package/src/api/tools/test/lib/fixtures/example3-flow.json +148 -0
  73. package/src/api/tools/test/lib/fixtures/package.json +6 -0
  74. package/src/api/tools/test/lib/fixtures/s3-event.js +43 -0
  75. package/src/api/tools/test/lib/reporters/index.js +120 -0
  76. package/src/server/DesignerServer.js +141 -0
@@ -0,0 +1,171 @@
1
+ var express = require('express');
2
+
3
+ var nodes = require('./nodes');
4
+ var flows = require('./flows');
5
+ var flow = require('./flow');
6
+ var context = require('./context');
7
+ var util = require('./util');
8
+
9
+ let errorHandler = (err, req, res, next) => {
10
+ console.error(err.stack);
11
+ res.status(500).send('Something broke!');
12
+ }
13
+
14
+ function needsPermission(permission) {
15
+ return function (req, res, next) {
16
+ // if (userHasPermission(req.user, permission)) {
17
+ next();
18
+ // } else {
19
+ // res.status(401).send('Unauthorized');
20
+ // }
21
+ };
22
+ }
23
+
24
+ module.exports = {
25
+ init: function (runtime) {
26
+ // Load all internal runtime APIs
27
+ let runtimeAPI = require('../index');
28
+ runtimeAPI.init(runtime);
29
+
30
+ flows.init(runtimeAPI);
31
+ flow.init(runtimeAPI);
32
+ nodes.init(runtimeAPI);
33
+ context.init(runtimeAPI);
34
+ util.init(runtimeAPI);
35
+
36
+ var adminApp = express();
37
+
38
+ // Flows
39
+ adminApp.get(
40
+ '/flows',
41
+ needsPermission('flows.read'),
42
+ flows.get,
43
+ errorHandler
44
+ );
45
+ adminApp.post(
46
+ '/flows',
47
+ needsPermission('flows.write'),
48
+ flows.post,
49
+ errorHandler
50
+ );
51
+
52
+ // Flow
53
+ adminApp.get(
54
+ '/flow/:id',
55
+ needsPermission('flows.read'),
56
+ flow.get,
57
+ errorHandler
58
+ );
59
+ adminApp.post(
60
+ '/flow',
61
+ needsPermission('flows.write'),
62
+ flow.post,
63
+ errorHandler
64
+ );
65
+ adminApp.delete(
66
+ '/flow/:id',
67
+ needsPermission('flows.write'),
68
+ flow.delete,
69
+ errorHandler
70
+ );
71
+ adminApp.put(
72
+ '/flow/:id',
73
+ needsPermission('flows.write'),
74
+ flow.put,
75
+ errorHandler
76
+ );
77
+
78
+ // Nodes
79
+ adminApp.post(
80
+ '/nodes-reload',
81
+ needsPermission('nodes.write'),
82
+ nodes.reloadModules,
83
+ errorHandler
84
+ );
85
+ adminApp.get(
86
+ '/nodes',
87
+ needsPermission('nodes.read'),
88
+ nodes.getAll,
89
+ errorHandler
90
+ );
91
+ adminApp.post(
92
+ '/nodes',
93
+ needsPermission('nodes.write'),
94
+ nodes.post,
95
+ errorHandler
96
+ );
97
+ adminApp.get(
98
+ /^\/nodes\/((@[^\/]+\/)?[^\/]+)$/,
99
+ needsPermission('nodes.read'),
100
+ nodes.getModule,
101
+ errorHandler
102
+ );
103
+ adminApp.put(
104
+ /^\/nodes\/((@[^\/]+\/)?[^\/]+)$/,
105
+ needsPermission('nodes.write'),
106
+ nodes.putModule,
107
+ errorHandler
108
+ );
109
+ adminApp.delete(
110
+ /^\/nodes\/((@[^\/]+\/)?[^\/]+)$/,
111
+ needsPermission('nodes.write'),
112
+ nodes.delete,
113
+ errorHandler
114
+ );
115
+ adminApp.get(
116
+ /^\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,
117
+ needsPermission('nodes.read'),
118
+ nodes.getSet,
119
+ errorHandler
120
+ );
121
+ adminApp.put(
122
+ /^\/nodes\/((@[^\/]+\/)?[^\/]+)\/([^\/]+)$/,
123
+ needsPermission('nodes.write'),
124
+ nodes.putSet,
125
+ errorHandler
126
+ );
127
+
128
+ // Context
129
+ adminApp.get(
130
+ '/context/:scope(global)',
131
+ needsPermission('context.read'),
132
+ context.get,
133
+ errorHandler
134
+ );
135
+ adminApp.get(
136
+ '/context/:scope(global)/*',
137
+ needsPermission('context.read'),
138
+ context.get,
139
+ errorHandler
140
+ );
141
+ adminApp.get(
142
+ '/context/:scope(node|flow)/:id',
143
+ needsPermission('context.read'),
144
+ context.get,
145
+ errorHandler
146
+ );
147
+ adminApp.get(
148
+ '/context/:scope(node|flow)/:id/*',
149
+ needsPermission('context.read'),
150
+ context.get,
151
+ errorHandler
152
+ );
153
+
154
+ // adminApp.delete("/context/:scope(global)",needsPermission("context.write"),context.delete,errorHandler);
155
+ adminApp.delete(
156
+ '/context/:scope(global)/*',
157
+ needsPermission('context.write'),
158
+ context.delete,
159
+ errorHandler
160
+ );
161
+ // adminApp.delete("/context/:scope(node|flow)/:id",needsPermission("context.write"),context.delete,errorHandler);
162
+ adminApp.delete(
163
+ '/context/:scope(node|flow)/:id/*',
164
+ needsPermission('context.write'),
165
+ context.delete,
166
+ errorHandler
167
+ );
168
+
169
+ return adminApp;
170
+ }
171
+ };
@@ -0,0 +1,164 @@
1
+ var apiUtils = require('./util');
2
+
3
+ var runtimeAPI;
4
+
5
+ module.exports = {
6
+ init: function(_runtimeAPI) {
7
+ runtimeAPI = _runtimeAPI;
8
+ },
9
+ getAll: function(req, res) {
10
+ var opts = {
11
+ user: req.user
12
+ };
13
+ if (req.get('accept') == 'application/json') {
14
+ runtimeAPI.nodes.getNodeList(opts).then(function(list) {
15
+ res.json(list);
16
+ });
17
+ } else {
18
+ opts.lang = apiUtils.determineLangFromHeaders(req.acceptsLanguages());
19
+ runtimeAPI.nodes.getNodeConfigs(opts).then(function(configs) {
20
+ res.send(configs);
21
+ });
22
+ }
23
+ },
24
+
25
+ post: function(req, res) {
26
+ var opts = {
27
+ user: req.user,
28
+ module: req.body.module,
29
+ version: req.body.version
30
+ };
31
+ runtimeAPI.nodes
32
+ .addModule(opts)
33
+ .then(function(info) {
34
+ res.json(info);
35
+ })
36
+ .catch(function(err) {
37
+ apiUtils.rejectHandler(req, res, err);
38
+ });
39
+ },
40
+
41
+ delete: function(req, res) {
42
+ var opts = {
43
+ user: req.user,
44
+ module: req.params[0]
45
+ };
46
+ runtimeAPI.nodes
47
+ .removeModule(opts)
48
+ .then(function() {
49
+ res.status(204).end();
50
+ })
51
+ .catch(function(err) {
52
+ apiUtils.rejectHandler(req, res, err);
53
+ });
54
+ },
55
+
56
+ getSet: function(req, res) {
57
+ var opts = {
58
+ user: req.user,
59
+ id: req.params[0] + '/' + req.params[2]
60
+ };
61
+ if (req.get('accept') === 'application/json') {
62
+ runtimeAPI.nodes
63
+ .getNodeInfo(opts)
64
+ .then(function(result) {
65
+ res.send(result);
66
+ })
67
+ .catch(function(err) {
68
+ apiUtils.rejectHandler(req, res, err);
69
+ });
70
+ } else {
71
+ opts.lang = apiUtils.determineLangFromHeaders(req.acceptsLanguages());
72
+ runtimeAPI.nodes
73
+ .getNodeConfig(opts)
74
+ .then(function(result) {
75
+ return res.send(result);
76
+ })
77
+ .catch(function(err) {
78
+ apiUtils.rejectHandler(req, res, err);
79
+ });
80
+ }
81
+ },
82
+
83
+ getModule: function(req, res) {
84
+ var opts = {
85
+ user: req.user,
86
+ module: req.params[0]
87
+ };
88
+ runtimeAPI.nodes
89
+ .getModuleInfo(opts)
90
+ .then(function(result) {
91
+ res.send(result);
92
+ })
93
+ .catch(function(err) {
94
+ apiUtils.rejectHandler(req, res, err);
95
+ });
96
+ },
97
+
98
+ reloadModules: async function(req, res) {
99
+ // Ensure backwards compatibility with old runtimes. Eg. user declares an external runtime to power its flows other than the embeded one
100
+ if (typeof runtimeAPI.httpNode.refreshingUserMiddlewares === 'function'){
101
+ runtimeAPI.httpNode.refreshingUserMiddlewares();
102
+ }
103
+
104
+ let result = await runtimeAPI.nodes.reloadModules();
105
+ res.send(result);
106
+ },
107
+
108
+ putSet: function(req, res) {
109
+ var body = req.body;
110
+ if (!body.hasOwnProperty('enabled')) {
111
+ // log.audit({event: "nodes.module.set",error:"invalid_request"},req);
112
+ res
113
+ .status(400)
114
+ .json({ code: 'invalid_request', message: 'Invalid request' });
115
+ return;
116
+ }
117
+ var opts = {
118
+ user: req.user,
119
+ id: req.params[0] + '/' + req.params[2],
120
+ enabled: body.enabled
121
+ };
122
+ runtimeAPI.nodes
123
+ .setNodeSetState(opts)
124
+ .then(function(result) {
125
+ res.send(result);
126
+ })
127
+ .catch(function(err) {
128
+ apiUtils.rejectHandler(req, res, err);
129
+ });
130
+ },
131
+
132
+ putModule: function(req, res) {
133
+ var body = req.body;
134
+ if (!body.hasOwnProperty('enabled')) {
135
+ // log.audit({event: "nodes.module.set",error:"invalid_request"},req);
136
+ res
137
+ .status(400)
138
+ .json({ code: 'invalid_request', message: 'Invalid request' });
139
+ return;
140
+ }
141
+ var opts = {
142
+ user: req.user,
143
+ module: req.params[0],
144
+ enabled: body.enabled
145
+ };
146
+ runtimeAPI.nodes
147
+ .setModuleState(opts)
148
+ .then(function(result) {
149
+ res.send(result);
150
+ })
151
+ .catch(function(err) {
152
+ apiUtils.rejectHandler(req, res, err);
153
+ });
154
+ },
155
+
156
+ getIcons: function(req, res) {
157
+ var opts = {
158
+ user: req.user
159
+ };
160
+ runtimeAPI.nodes.getIconList(opts).then(function(list) {
161
+ res.json(list);
162
+ });
163
+ }
164
+ };
@@ -0,0 +1,53 @@
1
+ let runtimeAPI;
2
+ let log;
3
+
4
+ module.exports = {
5
+ init: function(_runtimeAPI) {
6
+ runtimeAPI = _runtimeAPI;
7
+ log = runtimeAPI.log;
8
+ },
9
+ errorHandler: function(err, req, res, next) {
10
+ //TODO: why this when rejectHandler also?!
11
+
12
+ if (err.message === 'request entity too large') {
13
+ log.error(err);
14
+ } else {
15
+ log.error(err.stack);
16
+ }
17
+ log.audit(
18
+ {
19
+ event: 'api.error',
20
+ error: err.code || 'unexpected_error',
21
+ message: err.toString()
22
+ },
23
+ req
24
+ );
25
+ res
26
+ .status(400)
27
+ .json({ error: 'unexpected_error', message: err.toString() });
28
+ },
29
+
30
+ determineLangFromHeaders: function(acceptedLanguages) {
31
+ var lang = 'en-US';
32
+ acceptedLanguages = acceptedLanguages || [];
33
+ if (acceptedLanguages.length >= 1) {
34
+ lang = acceptedLanguages[0];
35
+ }
36
+ return lang;
37
+ },
38
+ rejectHandler: function(req, res, err) {
39
+ //TODO: why this when errorHandler also?!
40
+ log.audit(
41
+ {
42
+ event: 'api.error',
43
+ error: err.code || 'unexpected_error',
44
+ message: err.message || err.toString()
45
+ },
46
+ req
47
+ );
48
+ res.status(err.status || 400).json({
49
+ code: err.code || 'unexpected_error',
50
+ message: err.message || err.toString()
51
+ });
52
+ }
53
+ };
@@ -0,0 +1,287 @@
1
+ /**
2
+ * @mixin @kumologica-core/runtime_settings
3
+ */
4
+
5
+ var util = require('util');
6
+ var runtime;
7
+
8
+ function extend(target, source) {
9
+ var keys = Object.keys(source);
10
+ var i = keys.length;
11
+ while (i--) {
12
+ var value = source[keys[i]];
13
+ var type = typeof value;
14
+ if (
15
+ type === 'string' ||
16
+ type === 'number' ||
17
+ type === 'boolean' ||
18
+ Array.isArray(value)
19
+ ) {
20
+ target[keys[i]] = value;
21
+ } else if (value === null) {
22
+ if (target.hasOwnProperty(keys[i])) {
23
+ delete target[keys[i]];
24
+ }
25
+ } else {
26
+ // Object
27
+ if (target.hasOwnProperty(keys[i])) {
28
+ target[keys[i]] = extend(target[keys[i]], value);
29
+ } else {
30
+ target[keys[i]] = value;
31
+ }
32
+ }
33
+ }
34
+ return target;
35
+ }
36
+
37
+ function getSSHKeyUsername(userObj) {
38
+ var username = '__default';
39
+ if (userObj && userObj.username) {
40
+ username = userObj.username;
41
+ }
42
+ return username;
43
+ }
44
+ var api = (module.exports = {
45
+ init: function (_runtime) {
46
+ runtime = _runtime;
47
+ },
48
+ // Read a particular key from the runtime settings - unsafe call (?)
49
+ get: function (key) {
50
+ return runtime.settings[key];
51
+ },
52
+ /**
53
+ * Gets the runtime settings object
54
+ * @param {Object} opts
55
+ * @param {User} opts.user - the user calling the api
56
+ * @return {Promise<Object>} - the runtime settings
57
+ * @memberof @kumologica-core/runtime_settings
58
+ */
59
+ getRuntimeSettings: function (opts) {
60
+ return new Promise(function (resolve, reject) {
61
+ try {
62
+ var safeSettings = {
63
+ httpNodeRoot: runtime.settings.httpNodeRoot || '/',
64
+ version: runtime.settings.version,
65
+ userDir: runtime.settings.userDir,
66
+ };
67
+ if (opts && opts.user) {
68
+ safeSettings.user = {};
69
+ var props = ['anonymous', 'username', 'image', 'permissions'];
70
+ props.forEach((prop) => {
71
+ if (opts.user.hasOwnProperty(prop)) {
72
+ safeSettings.user[prop] = opts.user[prop];
73
+ }
74
+ });
75
+ }
76
+
77
+ safeSettings.context = runtime.nodes.listContextStores();
78
+
79
+ if (util.isArray(runtime.settings.paletteCategories)) {
80
+ safeSettings.paletteCategories = runtime.settings.paletteCategories;
81
+ }
82
+
83
+ if (runtime.settings.flowFilePretty) {
84
+ safeSettings.flowFilePretty = runtime.settings.flowFilePretty;
85
+ }
86
+
87
+ if (!runtime.nodes.paletteEditorEnabled()) {
88
+ safeSettings.editorTheme = safeSettings.editorTheme || {};
89
+ safeSettings.editorTheme.palette =
90
+ safeSettings.editorTheme.palette || {};
91
+ safeSettings.editorTheme.palette.editable = false;
92
+ }
93
+ if (runtime.storage.projects) {
94
+ var activeProject = runtime.storage.projects.getActiveProject();
95
+ if (activeProject) {
96
+ safeSettings.project = activeProject;
97
+ } else if (runtime.storage.projects.flowFileExists()) {
98
+ safeSettings.files = {
99
+ flow: runtime.storage.projects.getFlowFilename(),
100
+ credentials: runtime.storage.projects.getCredentialsFilename(),
101
+ };
102
+ }
103
+ safeSettings.git = {
104
+ globalUser: runtime.storage.projects.getGlobalGitUser(),
105
+ };
106
+ }
107
+
108
+ safeSettings.flowEncryptionType = runtime.nodes.getCredentialKeyType();
109
+
110
+ runtime.settings.exportNodeSettings(safeSettings);
111
+
112
+ resolve(safeSettings);
113
+ } catch (err) {
114
+ console.log(err);
115
+ }
116
+ });
117
+ },
118
+
119
+ /**
120
+ * Gets an individual user's settings object
121
+ * @param {Object} opts
122
+ * @param {User} opts.user - the user calling the api
123
+ * @return {Promise<Object>} - the user settings
124
+ * @memberof @kumologica-core/runtime_settings
125
+ */
126
+ getUserSettings: function (opts) {
127
+ opts = opts || {};
128
+ var username;
129
+ if (!opts.user || opts.user.anonymous) {
130
+ username = '_';
131
+ } else {
132
+ username = opts.user.username;
133
+ }
134
+ return Promise.resolve(runtime.settings.getUserSettings(username) || {});
135
+ },
136
+
137
+ /**
138
+ * Updates an individual user's settings object.
139
+ * @param {Object} opts
140
+ * @param {User} opts.user - the user calling the api
141
+ * @param {Object} opts.settings - the updates to the user settings
142
+ * @return {Promise<Object>} - the user settings
143
+ * @memberof @kumologica-core/runtime_settings
144
+ */
145
+ updateUserSettings: function (opts) {
146
+ var username;
147
+ if (!opts.user || opts.user.anonymous) {
148
+ username = '_';
149
+ } else {
150
+ username = opts.user.username;
151
+ }
152
+ return new Promise(function (resolve, reject) {
153
+ var currentSettings = runtime.settings.getUserSettings(username) || {};
154
+ currentSettings = extend(currentSettings, opts.settings);
155
+ try {
156
+ runtime.settings
157
+ .setUserSettings(username, currentSettings)
158
+ .then(function () {
159
+ runtime.log.audit({ event: 'settings.update', username: username });
160
+ return resolve();
161
+ })
162
+ .catch(function (err) {
163
+ runtime.log.audit({
164
+ event: 'settings.update',
165
+ username: username,
166
+ error: err.code || 'unexpected_error',
167
+ message: err.toString(),
168
+ });
169
+ err.status = 400;
170
+ return reject(err);
171
+ });
172
+ } catch (err) {
173
+ runtime.log.warn(`Cannot save user settings: ${err.toString()}`);
174
+ runtime.log.audit({
175
+ event: 'settings.update',
176
+ username: username,
177
+ error: err.code || 'unexpected_error',
178
+ message: err.toString(),
179
+ });
180
+ err.status = 400;
181
+ return reject(err);
182
+ }
183
+ });
184
+ },
185
+
186
+ /**
187
+ * Gets a list of a user's ssh keys
188
+ * @param {Object} opts
189
+ * @param {User} opts.user - the user calling the api
190
+ * @return {Promise<Object>} - the user's ssh keys
191
+ * @memberof @kumologica-core/runtime_settings
192
+ */
193
+ getUserKeys: function (opts) {
194
+ return new Promise(function (resolve, reject) {
195
+ var username = getSSHKeyUsername(opts.user);
196
+ runtime.storage.projects.ssh
197
+ .listSSHKeys(username)
198
+ .then(function (list) {
199
+ return resolve(list);
200
+ })
201
+ .catch(function (err) {
202
+ err.status = 400;
203
+ return reject(err);
204
+ });
205
+ });
206
+ },
207
+
208
+ /**
209
+ * Gets a user's ssh public key
210
+ * @param {Object} opts
211
+ * @param {User} opts.user - the user calling the api
212
+ * @param {User} opts.id - the id of the key to return
213
+ * @return {Promise<String>} - the user's ssh public key
214
+ * @memberof @kumologica-core/runtime_settings
215
+ */
216
+ getUserKey: function (opts) {
217
+ return new Promise(function (resolve, reject) {
218
+ var username = getSSHKeyUsername(opts.user);
219
+ // console.log('username:', username);
220
+ runtime.storage.projects.ssh
221
+ .getSSHKey(username, opts.id)
222
+ .then(function (data) {
223
+ if (data) {
224
+ return resolve(data);
225
+ } else {
226
+ var err = new Error('Key not found');
227
+ err.code = 'not_found';
228
+ err.status = 404;
229
+ return reject(err);
230
+ }
231
+ })
232
+ .catch(function (err) {
233
+ err.status = 400;
234
+ return reject(err);
235
+ });
236
+ });
237
+ },
238
+
239
+ /**
240
+ * Generates a new ssh key pair
241
+ * @param {Object} opts
242
+ * @param {User} opts.user - the user calling the api
243
+ * @param {User} opts.name - the id of the key to return
244
+ * @param {User} opts.password - (optional) the password for the key pair
245
+ * @param {User} opts.comment - (option) a comment to associate with the key pair
246
+ * @param {User} opts.size - (optional) the size of the key. Default: 2048
247
+ * @return {Promise<String>} - the id of the generated key
248
+ * @memberof @kumologica-core/runtime_settings
249
+ */
250
+ generateUserKey: function (opts) {
251
+ return new Promise(function (resolve, reject) {
252
+ var username = getSSHKeyUsername(opts.user);
253
+ runtime.storage.projects.ssh
254
+ .generateSSHKey(username, opts)
255
+ .then(function (name) {
256
+ return resolve(name);
257
+ })
258
+ .catch(function (err) {
259
+ err.status = 400;
260
+ return reject(err);
261
+ });
262
+ });
263
+ },
264
+
265
+ /**
266
+ * Deletes a user's ssh key pair
267
+ * @param {Object} opts
268
+ * @param {User} opts.user - the user calling the api
269
+ * @param {User} opts.id - the id of the key to delete
270
+ * @return {Promise} - resolves when deleted
271
+ * @memberof @kumologica-core/runtime_settings
272
+ */
273
+ removeUserKey: function (opts) {
274
+ return new Promise(function (resolve, reject) {
275
+ var username = getSSHKeyUsername(opts.user);
276
+ runtime.storage.projects.ssh
277
+ .deleteSSHKey(username, opts.id)
278
+ .then(function () {
279
+ return resolve();
280
+ })
281
+ .catch(function (err) {
282
+ err.status = 400;
283
+ return reject(err);
284
+ });
285
+ });
286
+ },
287
+ });