puppetfactory 0.4.0

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 (95) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +13 -0
  3. data/README.md +0 -0
  4. data/bin/pfsh +31 -0
  5. data/bin/puppetfactory +153 -0
  6. data/lib/puppetfactory.rb +300 -0
  7. data/lib/puppetfactory/cli.rb +114 -0
  8. data/lib/puppetfactory/dashboard/rake_tasks.rb +69 -0
  9. data/lib/puppetfactory/dashboard/serverspec_helper.rb +84 -0
  10. data/lib/puppetfactory/dashboard/spec_helper.rb +26 -0
  11. data/lib/puppetfactory/helpers.rb +37 -0
  12. data/lib/puppetfactory/monkeypatches.rb +30 -0
  13. data/lib/puppetfactory/plugins.rb +11 -0
  14. data/lib/puppetfactory/plugins/certificates.rb +28 -0
  15. data/lib/puppetfactory/plugins/classification.rb +75 -0
  16. data/lib/puppetfactory/plugins/code_manager.rb +156 -0
  17. data/lib/puppetfactory/plugins/console_user.rb +62 -0
  18. data/lib/puppetfactory/plugins/dashboard.rb +128 -0
  19. data/lib/puppetfactory/plugins/docker.rb +193 -0
  20. data/lib/puppetfactory/plugins/example.rb +88 -0
  21. data/lib/puppetfactory/plugins/github.rb +102 -0
  22. data/lib/puppetfactory/plugins/gitlab.rb +62 -0
  23. data/lib/puppetfactory/plugins/hooks.rb +46 -0
  24. data/lib/puppetfactory/plugins/login_shell.rb +10 -0
  25. data/lib/puppetfactory/plugins/logs.rb +34 -0
  26. data/lib/puppetfactory/plugins/r10k.rb +112 -0
  27. data/lib/puppetfactory/plugins/shell_user.rb +69 -0
  28. data/lib/puppetfactory/plugins/user_environment.rb +77 -0
  29. data/public/dashboard.js +100 -0
  30. data/public/font-awesome/css/font-awesome.css +2199 -0
  31. data/public/font-awesome/css/font-awesome.min.css +4 -0
  32. data/public/font-awesome/fonts/FontAwesome.otf +0 -0
  33. data/public/font-awesome/fonts/fontawesome-webfont.eot +0 -0
  34. data/public/font-awesome/fonts/fontawesome-webfont.svg +685 -0
  35. data/public/font-awesome/fonts/fontawesome-webfont.ttf +0 -0
  36. data/public/font-awesome/fonts/fontawesome-webfont.woff +0 -0
  37. data/public/font-awesome/fonts/fontawesome-webfont.woff2 +0 -0
  38. data/public/gitviz/LICENSE.md +20 -0
  39. data/public/gitviz/README.md +13 -0
  40. data/public/gitviz/css/explaingit.css +227 -0
  41. data/public/gitviz/css/vendor/1140.css +130 -0
  42. data/public/gitviz/images/forkme_right_red_aa0000.png +0 -0
  43. data/public/gitviz/images/grippy-close.png +0 -0
  44. data/public/gitviz/images/grippy.png +0 -0
  45. data/public/gitviz/images/prompt.gif +0 -0
  46. data/public/gitviz/index.html +734 -0
  47. data/public/gitviz/js/controlbox.js +459 -0
  48. data/public/gitviz/js/explaingit.js +74 -0
  49. data/public/gitviz/js/historyview.js +979 -0
  50. data/public/gitviz/js/main.js +56 -0
  51. data/public/gitviz/js/vendor/d3.min.js +4 -0
  52. data/public/gitviz/js/vendor/jquery-latest.min.js +6 -0
  53. data/public/gitviz/js/vendor/normalize.css +396 -0
  54. data/public/gitviz/js/vendor/require.min.js +35 -0
  55. data/public/gitviz/memtest.html +44 -0
  56. data/public/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  57. data/public/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  58. data/public/images/ui-bg_flat_10_000000_40x100.png +0 -0
  59. data/public/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  60. data/public/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  61. data/public/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  62. data/public/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  63. data/public/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  64. data/public/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  65. data/public/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  66. data/public/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  67. data/public/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  68. data/public/images/ui-icons_222222_256x240.png +0 -0
  69. data/public/images/ui-icons_228ef1_256x240.png +0 -0
  70. data/public/images/ui-icons_454545_256x240.png +0 -0
  71. data/public/images/ui-icons_ef8c08_256x240.png +0 -0
  72. data/public/images/ui-icons_ffd27a_256x240.png +0 -0
  73. data/public/images/ui-icons_ffffff_256x240.png +0 -0
  74. data/public/jquery-1.11.1.min.js +4 -0
  75. data/public/jquery-ui.css +464 -0
  76. data/public/jquery-ui.min.css +7 -0
  77. data/public/jquery-ui.min.js +13 -0
  78. data/public/jquery-ui.structure.min.css +5 -0
  79. data/public/jquery-ui.theme.min.css +5 -0
  80. data/public/jquery.activity-indicator-1.0.0.min.js +10 -0
  81. data/public/jquery.js +9789 -0
  82. data/public/loginscripts.js +18 -0
  83. data/public/scripts.js +36 -0
  84. data/public/style.css +193 -0
  85. data/public/usermanagement.js +133 -0
  86. data/templates/init_scripts.erb +10 -0
  87. data/templates/puppet.conf.erb +10 -0
  88. data/templates/site.pp.erb +50 -0
  89. data/views/dashboard.erb +62 -0
  90. data/views/home.erb +43 -0
  91. data/views/index.erb +29 -0
  92. data/views/logs.erb +26 -0
  93. data/views/shell.erb +35 -0
  94. data/views/users.erb +69 -0
  95. metadata +256 -0
@@ -0,0 +1,459 @@
1
+ define(['d3'], function () {
2
+ "use strict";
3
+
4
+ /**
5
+ * @class ControlBox
6
+ * @constructor
7
+ */
8
+ function ControlBox(config) {
9
+ this.historyView = config.historyView;
10
+ this.originView = config.originView;
11
+ this.initialMessage = config.initialMessage || 'Enter git commands below.';
12
+ this._commandHistory = [];
13
+ this._currentCommand = -1;
14
+ this._tempCommand = '';
15
+ this.rebaseConfig = {}; // to configure branches for rebase
16
+ }
17
+
18
+ ControlBox.prototype = {
19
+ render: function (container) {
20
+ var cBox = this,
21
+ cBoxContainer, log, input;
22
+
23
+ cBoxContainer = container.append('div')
24
+ .classed('control-box', true);
25
+
26
+ cBoxContainer.style('height', this.historyView.height + 5 + 'px');
27
+
28
+ log = cBoxContainer.append('div')
29
+ .classed('log', true)
30
+ .style('height', this.historyView.height - 20 + 'px');
31
+
32
+ input = cBoxContainer.append('input')
33
+ .attr('type', 'text')
34
+ .attr('placeholder', 'enter git command');
35
+
36
+ input.on('keyup', function () {
37
+ var e = d3.event;
38
+
39
+ switch (e.keyCode) {
40
+ case 13:
41
+ if (this.value.trim() === '') {
42
+ break;
43
+ }
44
+
45
+ cBox._commandHistory.unshift(this.value);
46
+ cBox._tempCommand = '';
47
+ cBox._currentCommand = -1;
48
+ cBox.command(this.value);
49
+ this.value = '';
50
+ e.stopImmediatePropagation();
51
+ break;
52
+ case 38:
53
+ var previousCommand = cBox._commandHistory[cBox._currentCommand + 1];
54
+ if (cBox._currentCommand === -1) {
55
+ cBox._tempCommand = this.value;
56
+ }
57
+
58
+ if (typeof previousCommand === 'string') {
59
+ cBox._currentCommand += 1;
60
+ this.value = previousCommand;
61
+ this.value = this.value; // set cursor to end
62
+ }
63
+ e.stopImmediatePropagation();
64
+ break;
65
+ case 40:
66
+ var nextCommand = cBox._commandHistory[cBox._currentCommand - 1];
67
+ if (typeof nextCommand === 'string') {
68
+ cBox._currentCommand -= 1;
69
+ this.value = nextCommand;
70
+ this.value = this.value; // set cursor to end
71
+ } else {
72
+ cBox._currentCommand = -1;
73
+ this.value = cBox._tempCommand;
74
+ this.value = this.value; // set cursor to end
75
+ }
76
+ e.stopImmediatePropagation();
77
+ break;
78
+ }
79
+ });
80
+
81
+ this.container = cBoxContainer;
82
+ this.log = log;
83
+ this.input = input;
84
+
85
+ this.info(this.initialMessage);
86
+ },
87
+
88
+ destroy: function () {
89
+ this.log.remove();
90
+ this.input.remove();
91
+ this.container.remove();
92
+
93
+ for (var prop in this) {
94
+ if (this.hasOwnProperty(prop)) {
95
+ this[prop] = null;
96
+ }
97
+ }
98
+ },
99
+
100
+ _scrollToBottom: function () {
101
+ var log = this.log.node();
102
+ log.scrollTop = log.scrollHeight;
103
+ },
104
+
105
+ command: function (entry) {
106
+ if (entry.trim === '') {
107
+ return;
108
+ }
109
+
110
+ var split = entry.split(' ');
111
+
112
+ this.log.append('div')
113
+ .classed('command-entry', true)
114
+ .html(entry);
115
+
116
+ this._scrollToBottom();
117
+
118
+ if (split[0] !== 'git') {
119
+ return this.error();
120
+ }
121
+
122
+ var method = split[1],
123
+ args = split.slice(2);
124
+
125
+ try {
126
+ if (typeof this[method] === 'function') {
127
+ this[method](args);
128
+ } else {
129
+ this.error();
130
+ }
131
+ } catch (ex) {
132
+ var msg = (ex && ex.message) ? ex.message: null;
133
+ this.error(msg);
134
+ }
135
+ },
136
+
137
+ info: function (msg) {
138
+ this.log.append('div').classed('info', true).html(msg);
139
+ this._scrollToBottom();
140
+ },
141
+
142
+ error: function (msg) {
143
+ msg = msg || 'I don\'t understand that.';
144
+ this.log.append('div').classed('error', true).html(msg);
145
+ this._scrollToBottom();
146
+ },
147
+
148
+ commit: function () {
149
+ this.historyView.commit();
150
+ },
151
+
152
+ branch: function (args) {
153
+ if (args.length < 1) {
154
+ this.info(
155
+ 'You need to give a branch name. ' +
156
+ 'Normally if you don\'t give a name, ' +
157
+ 'this command will list your local branches on the screen.'
158
+ );
159
+
160
+ return;
161
+ }
162
+
163
+ while (args.length > 0) {
164
+ var arg = args.shift();
165
+
166
+ switch (arg) {
167
+ case '--remote':
168
+ this.info(
169
+ 'This command normally displays all of your remote tracking branches.'
170
+ );
171
+ args.length = 0;
172
+ break;
173
+ case '-d':
174
+ var name = args.pop();
175
+ this.historyView.deleteBranch(name);
176
+ break;
177
+ default:
178
+ var remainingArgs = [arg].concat(args);
179
+ args.length = 0;
180
+ this.historyView.branch(remainingArgs.join(' '));
181
+ }
182
+ }
183
+ },
184
+
185
+ checkout: function (args) {
186
+ while (args.length > 0) {
187
+ var arg = args.shift();
188
+
189
+ switch (arg) {
190
+ case '-b':
191
+ var name = args[args.length - 1];
192
+ try {
193
+ this.historyView.branch(name);
194
+ } catch (err) {
195
+ if (err.message.indexOf('already exists') === -1) {
196
+ throw new Error(err.message);
197
+ }
198
+ }
199
+ break;
200
+ default:
201
+ var remainingArgs = [arg].concat(args);
202
+ args.length = 0;
203
+ this.historyView.checkout(remainingArgs.join(' '));
204
+ }
205
+ }
206
+ },
207
+
208
+ reset: function (args) {
209
+ while (args.length > 0) {
210
+ var arg = args.shift();
211
+
212
+ switch (arg) {
213
+ case '--soft':
214
+ this.info(
215
+ 'The "--soft" flag works in real git, but ' +
216
+ 'I am unable to show you how it works in this demo. ' +
217
+ 'So I am just going to show you what "--hard" looks like instead.'
218
+ );
219
+ break;
220
+ case '--mixed':
221
+ this.info(
222
+ 'The "--mixed" flag works in real git, but ' +
223
+ 'I am unable to show you how it works in this demo.'
224
+ );
225
+ break;
226
+ case '--hard':
227
+ this.historyView.reset(args.join(' '));
228
+ args.length = 0;
229
+ break;
230
+ default:
231
+ var remainingArgs = [arg].concat(args);
232
+ args.length = 0;
233
+ this.info('Assuming "--hard".');
234
+ this.historyView.reset(remainingArgs.join(' '));
235
+ }
236
+ }
237
+ },
238
+
239
+ clean: function (args) {
240
+ this.info('Deleting all of your untracked files...');
241
+ },
242
+
243
+ revert: function (args) {
244
+ this.historyView.revert(args.shift());
245
+ },
246
+
247
+ merge: function (args) {
248
+ var ref = args.shift(),
249
+ result = this.historyView.merge(ref);
250
+
251
+ if (result === 'Fast-Forward') {
252
+ this.info('You have performed a fast-forward merge.');
253
+ }
254
+ },
255
+
256
+ rebase: function (args) {
257
+ var ref = args.shift(),
258
+ result = this.historyView.rebase(ref);
259
+
260
+ if (result === 'Fast-Forward') {
261
+ this.info('Fast-forwarded to ' + ref + '.');
262
+ }
263
+ },
264
+
265
+ fetch: function () {
266
+ if (!this.originView) {
267
+ throw new Error('There is no remote server to fetch from.');
268
+ }
269
+
270
+ var origin = this.originView,
271
+ local = this.historyView,
272
+ remotePattern = /^origin\/([^\/]+)$/,
273
+ rtb, isRTB, fb,
274
+ fetchBranches = {},
275
+ fetchIds = [], // just to make sure we don't fetch the same commit twice
276
+ fetchCommits = [], fetchCommit,
277
+ resultMessage = '';
278
+
279
+ // determine which branches to fetch
280
+ for (rtb = 0; rtb < local.branches.length; rtb++) {
281
+ isRTB = remotePattern.exec(local.branches[rtb]);
282
+ if (isRTB) {
283
+ fetchBranches[isRTB[1]] = 0;
284
+ }
285
+ }
286
+
287
+ // determine which commits the local repo is missing from the origin
288
+ for (fb in fetchBranches) {
289
+ if (origin.branches.indexOf(fb) > -1) {
290
+ fetchCommit = origin.getCommit(fb);
291
+
292
+ var notInLocal = local.getCommit(fetchCommit.id) === null;
293
+ while (notInLocal) {
294
+ if (fetchIds.indexOf(fetchCommit.id) === -1) {
295
+ fetchCommits.unshift(fetchCommit);
296
+ fetchIds.unshift(fetchCommit.id);
297
+ }
298
+ fetchBranches[fb] += 1;
299
+ fetchCommit = origin.getCommit(fetchCommit.parent);
300
+ notInLocal = local.getCommit(fetchCommit.id) === null;
301
+ }
302
+ }
303
+ }
304
+
305
+ // add the fetched commits to the local commit data
306
+ for (var fc = 0; fc < fetchCommits.length; fc++) {
307
+ fetchCommit = fetchCommits[fc];
308
+ local.commitData.push({
309
+ id: fetchCommit.id,
310
+ parent: fetchCommit.parent,
311
+ tags: []
312
+ });
313
+ }
314
+
315
+ // update the remote tracking branch tag locations
316
+ for (fb in fetchBranches) {
317
+ if (origin.branches.indexOf(fb) > -1) {
318
+ var remoteLoc = origin.getCommit(fb).id;
319
+ local.moveTag('origin/' + fb, remoteLoc);
320
+ }
321
+
322
+ resultMessage += 'Fetched ' + fetchBranches[fb] + ' commits on ' + fb + '.</br>';
323
+ }
324
+
325
+ this.info(resultMessage);
326
+
327
+ local.renderCommits();
328
+ },
329
+
330
+ pull: function (args) {
331
+ var control = this,
332
+ local = this.historyView,
333
+ currentBranch = local.currentBranch,
334
+ rtBranch = 'origin/' + currentBranch,
335
+ isFastForward = false;
336
+
337
+ this.fetch();
338
+
339
+ if (!currentBranch) {
340
+ throw new Error('You are not currently on a branch.');
341
+ }
342
+
343
+ if (local.branches.indexOf(rtBranch) === -1) {
344
+ throw new Error('Current branch is not set up for pulling.');
345
+ }
346
+
347
+ setTimeout(function () {
348
+ try {
349
+ if (args[0] === '--rebase' || control.rebaseConfig[currentBranch] === 'true') {
350
+ isFastForward = local.rebase(rtBranch) === 'Fast-Forward';
351
+ } else {
352
+ isFastForward = local.merge(rtBranch) === 'Fast-Forward';
353
+ }
354
+ } catch (error) {
355
+ control.error(error.message);
356
+ }
357
+
358
+ if (isFastForward) {
359
+ control.info('Fast-forwarded to ' + rtBranch + '.');
360
+ }
361
+ }, 750);
362
+ },
363
+
364
+ push: function (args) {
365
+ var control = this,
366
+ local = this.historyView,
367
+ remoteName = args.shift() || 'origin',
368
+ remote = this[remoteName + 'View'],
369
+ branchArgs = args.pop(),
370
+ localRef = local.currentBranch,
371
+ remoteRef = local.currentBranch,
372
+ localCommit, remoteCommit,
373
+ findCommitsToPush,
374
+ isCommonCommit,
375
+ toPush = [];
376
+
377
+ if (remoteName === 'history') {
378
+ throw new Error('Sorry, you can\'t have a remote named "history" in this example.');
379
+ }
380
+
381
+ if (!remote) {
382
+ throw new Error('There is no remote server named "' + remoteName + '".');
383
+ }
384
+
385
+ if (branchArgs) {
386
+ branchArgs = /^([^:]*)(:?)(.*)$/.exec(branchArgs);
387
+
388
+ branchArgs[1] && (localRef = branchArgs[1]);
389
+ branchArgs[2] === ':' && (remoteRef = branchArgs[3]);
390
+ }
391
+
392
+ if (local.branches.indexOf(localRef) === -1) {
393
+ throw new Error('Local ref: ' + localRef + ' does not exist.');
394
+ }
395
+
396
+ if (!remoteRef) {
397
+ throw new Error('No remote branch was specified to push to.');
398
+ }
399
+
400
+ localCommit = local.getCommit(localRef);
401
+ remoteCommit = remote.getCommit(remoteRef);
402
+
403
+ findCommitsToPush = function findCommitsToPush(localCommit) {
404
+ var commitToPush,
405
+ isCommonCommit = remote.getCommit(localCommit.id) !== null;
406
+
407
+ while (!isCommonCommit) {
408
+ commitToPush = {
409
+ id: localCommit.id,
410
+ parent: localCommit.parent,
411
+ tags: []
412
+ };
413
+
414
+ if (typeof localCommit.parent2 === 'string') {
415
+ commitToPush.parent2 = localCommit.parent2;
416
+ findCommitsToPush(local.getCommit(localCommit.parent2));
417
+ }
418
+
419
+ toPush.unshift(commitToPush);
420
+ localCommit = local.getCommit(localCommit.parent);
421
+ isCommonCommit = remote.getCommit(localCommit.id) !== null;
422
+ }
423
+ };
424
+
425
+ // push to an existing branch on the remote
426
+ if (remoteCommit && remote.branches.indexOf(remoteRef) > -1) {
427
+ if (!local.isAncestor(remoteCommit.id, localCommit.id)) {
428
+ throw new Error('Push rejected. Non fast-forward.');
429
+ }
430
+
431
+ isCommonCommit = localCommit.id === remoteCommit.id;
432
+
433
+ if (isCommonCommit) {
434
+ return this.info('Everything up-to-date.');
435
+ }
436
+
437
+ findCommitsToPush(localCommit);
438
+
439
+ remote.commitData = remote.commitData.concat(toPush);
440
+ remote.moveTag(remoteRef, toPush[toPush.length - 1].id);
441
+ remote.renderCommits();
442
+ } else {
443
+ this.info('Sorry, creating new remote branches is not supported yet.');
444
+ }
445
+ },
446
+
447
+ config: function (args) {
448
+ var path = args.shift().split('.');
449
+
450
+ if (path[0] === 'branch') {
451
+ if (path[2] === 'rebase') {
452
+ this.rebase[path[1]] = args.pop();
453
+ }
454
+ }
455
+ }
456
+ };
457
+
458
+ return ControlBox;
459
+ });