hieraviz 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c977dce78504ac761d4d7d6acd75ad95e873d2a7
4
- data.tar.gz: 9afaf6f7186ec5365fe685ff73ad4ce49a401f8d
3
+ metadata.gz: e4ae953c395227dd73942bc1faa14ab82e0d670c
4
+ data.tar.gz: 5a1e231af94bedf3f98770dab19e305d022c938d
5
5
  SHA512:
6
- metadata.gz: ee55dacc40305aec815eb61c1b718aff566fe8d8697f50eccd60dc6f645940ca27632395e1b3f1a11391e1223d003e85f698c551a93d8fd9fb7a1e20df072cbf
7
- data.tar.gz: 80e725f5a210c00e2e17b56ec50b1497dfe736292dbc9a8c0c1e70d3e1da69a9082cc5f0ddb097c4d15e3d191913af229c1980702dd376c0b8713c61e4130d73
6
+ metadata.gz: 8866fb2b55e06453abfbc2c22a6ec425c20c16c0aff3a4692baa11a495256bd8082eb8579507ab1bc310094b97d78518d2054a25bcdf6df9f6bae07878953f6c
7
+ data.tar.gz: b34d079696205abd7f81902f796cef8e1577b0215ae004532ae867195152d2117b87c7b5e0cf16fb84cf8504f7e73dcceee582720763e64009c9af0460afc619
data/CHANGELOG.md CHANGED
@@ -1,6 +1,14 @@
1
1
  Hieraviz Changelog
2
2
  ========================
3
3
 
4
+ ### v0.1.2 - 2016-02-22
5
+ - add a way to write custom local facts
6
+ - add display of nodes info on node panel
7
+ - make possible to change hiera variables per node
8
+ - fix farms list to read local files instead of puppetdb
9
+ - show actual number of nodes in farms list
10
+ - add storage of custom params per user
11
+
4
12
  ### v0.1.1 - 2016-01-29
5
13
  - add multibase ability
6
14
  - fix node navigation info/params/allparams
data/app/apiv1.rb CHANGED
@@ -17,20 +17,33 @@ module HieravizApp
17
17
  enable :sessions
18
18
  end
19
19
 
20
- helpers do
21
- def check_authorization
22
- if !session['access_token'] && !request.env['HTTP_X_AUTH']
23
- redirect '/v1/not_logged'
24
- else
25
- token = session['access_token'] || request.env['HTTP_X_AUTH']
26
- session_info = Hieraviz::Store.get(token, settings.configdata['session_renew'])
27
- if !session_info
28
- redirect '/v1/unauthorized'
20
+ case settings.configdata['auth_method']
21
+ when 'dummy'
22
+ helpers do
23
+ def check_authorization
24
+ true
25
+ end
26
+ end
27
+ when 'gitlab', 'http'
28
+ helpers do
29
+ def check_authorization
30
+ if !session['access_token'] && !request.env['HTTP_X_AUTH']
31
+ redirect '/v1/not_logged'
32
+ else
33
+ token = session['access_token'] || request.env['HTTP_X_AUTH']
34
+ session_info = Hieraviz::Store.get(token, settings.configdata['session_renew'])
35
+ if !session_info
36
+ redirect '/v1/unauthorized'
37
+ end
29
38
  end
30
39
  end
31
40
  end
32
41
  end
33
42
 
43
+ helpers do
44
+
45
+ end
46
+
34
47
  get %r{^/?([-_\.a-zA-Z0-9]+)?/nodes} do |base|
35
48
  check_authorization
36
49
  hieracles_config = prepare_config(base)
@@ -46,21 +59,43 @@ module HieravizApp
46
59
 
47
60
  get %r{^/?([-_\.a-zA-Z0-9]+)?/node/([-_\.a-zA-Z0-9]+)/params} do |base, node|
48
61
  check_authorization
49
- hieracles_config = prepare_config(base)
62
+ hieracles_config = prepare_config(base, node)
50
63
  node = Hieracles::Node.new(node, hieracles_config)
51
64
  json node.params
52
65
  end
53
66
 
54
67
  get %r{^/?([-_\.a-zA-Z0-9]+)?/node/([-_\.a-zA-Z0-9]+)/allparams} do |base, node|
55
68
  check_authorization
56
- hieracles_config = prepare_config(base)
69
+ hieracles_config = prepare_config(base, node)
57
70
  node = Hieracles::Node.new(node, hieracles_config)
58
71
  json node.params(false)
59
72
  end
60
73
 
74
+ get %r{^/?([-_\.a-zA-Z0-9]+)?/node/([-_\.a-zA-Z0-9]+)/facts} do |base, node|
75
+ check_authorization
76
+ hieracles_config = prepare_config(base, node)
77
+ facts = Hieraviz::Facts.new(settings.configdata['tmpdir'], base, node, get_username)
78
+ json facts.read
79
+ end
80
+
81
+ post %r{^/?([-_\.a-zA-Z0-9]+)?/node/([-_\.a-zA-Z0-9]+)/facts} do |base, node|
82
+ check_authorization
83
+ hieracles_config = prepare_config(base, node)
84
+ facts = Hieraviz::Facts.new(settings.configdata['tmpdir'], base, node, get_username)
85
+ data = JSON.parse(request.body.read.to_s)
86
+ json facts.write(data)
87
+ end
88
+
89
+ delete %r{^/?([-_\.a-zA-Z0-9]+)?/node/([-_\.a-zA-Z0-9]+)/facts} do |base, node|
90
+ check_authorization
91
+ hieracles_config = prepare_config(base, node)
92
+ facts = Hieraviz::Facts.new(settings.configdata['tmpdir'], base, node, get_username)
93
+ json facts.remove
94
+ end
95
+
61
96
  get %r{^/?([-_\.a-zA-Z0-9]+)?/node/([-_\.a-zA-Z0-9]+)$} do |base, node|
62
97
  check_authorization
63
- hieracles_config = prepare_config(base)
98
+ hieracles_config = prepare_config(base, node)
64
99
  node = Hieracles::Node.new(node, hieracles_config)
65
100
  json node.params
66
101
  end
@@ -68,15 +103,49 @@ module HieravizApp
68
103
  get %r{^/?([-_\.a-zA-Z0-9]+)?/farms} do |base|
69
104
  check_authorization
70
105
  hieracles_config = prepare_config(base)
71
- json Hieracles::Registry.farms(hieracles_config)
106
+ json Hieracles::Registry.farms_counted(hieracles_config, base)
107
+ end
108
+
109
+ get %r{^/?([-_\.a-zA-Z0-9]+)?/vars} do |base|
110
+ check_authorization
111
+ hieracles_config = prepare_config(base)
112
+ hiera = Hieracles::Hiera.new(hieracles_config)
113
+ json hiera.params
114
+ end
115
+
116
+ get %r{^/?([-_\.a-zA-Z0-9]+)?/node/([-_\.a-zA-Z0-9]+)/hierarchy} do |base, node|
117
+ check_authorization
118
+ hieracles_config = prepare_config(base, node)
119
+ hiera = Hieracles::Hiera.new(hieracles_config)
120
+ nodeinfo = Hieracles::Node.new(node, hieracles_config)
121
+ facts = Hieraviz::Facts.new(settings.configdata['tmpdir'], base, node, get_username)
122
+ puts facts.instance_variable_get(:@filename)
123
+ res = {
124
+ 'hiera' => hiera.hierarchy,
125
+ 'vars' => hiera.params,
126
+ 'info' => nodeinfo.info,
127
+ 'files' => nodeinfo.files,
128
+ 'facts' => facts.read,
129
+ 'defaults' => settings.configdata['defaultscope']
130
+ }
131
+ json res
132
+ end
133
+
134
+ get %r{^/?([-_\.a-zA-Z0-9]+)?/farm/([-_\.a-zA-Z0-9]+)$} do |base, farm|
135
+ check_authorization
136
+ hieracles_config = prepare_config(base)
137
+ nodes = Hieracles::Registry.nodes_data(hieracles_config, base).reduce({}) do |a, (k, v)|
138
+ a[k] = v if v['farm'] == farm
139
+ a
140
+ end
141
+ json nodes
72
142
  end
73
143
 
74
- # get '/farm/:n' do |farm|
75
- # check_authorization
76
- # req = Hieracles::Puppetdb::Request.new(settings.configdata['puppetdb'])
77
- # farm_nodes = req.facts('farm', farm)
78
- # json farm_nodes.data
79
- # end
144
+ get '/ppdb/events' do
145
+ check_authorization
146
+ puppetdb = Hieraviz::Puppetdb.new settings.configdata['puppetdb']
147
+ json puppetdb.events
148
+ end
80
149
 
81
150
  get '/not_logged' do
82
151
  json({ error: "Not connected." })
@@ -87,7 +156,7 @@ module HieravizApp
87
156
  end
88
157
 
89
158
  not_found do
90
- json({ error: "data not found" })
159
+ json({ error: "endpoint not found" })
91
160
  end
92
161
 
93
162
  end
data/app/common.rb CHANGED
@@ -14,23 +14,74 @@ module HieravizApp
14
14
  end
15
15
 
16
16
  helpers do
17
- def prepare_config(e)
18
- e = File.basename(settings.configdata['basepath']) unless e
17
+
18
+ case settings.configdata['auth_method']
19
+ when 'dummy'
20
+
21
+ def get_username
22
+ 'Dummy'
23
+ end
24
+ def get_userinfo
25
+ { 'username' => 'Dummy' }
26
+ end
27
+
28
+ when 'http'
29
+
30
+ def get_username
31
+ settings.configdata['http_auth']['username']
32
+ end
33
+ def get_userinfo
34
+ { 'username' => settings.configdata['http_auth']['username'] }
35
+ end
36
+
37
+ when 'gitlab'
38
+
39
+ def get_username
40
+ if session['access_token']
41
+ session_info = Hieraviz::Store.get(session['access_token'], settings.configdata['session_renew'])
42
+ if session_info
43
+ session_info['username']
44
+ else
45
+ ''
46
+ end
47
+ end
48
+ end
49
+
50
+ def get_userinfo
51
+ Hieraviz::Store.get(session['access_token'], settings.configdata['session_renew'])
52
+ end
53
+
54
+ end
55
+
56
+ def prepare_config(e, node = nil)
57
+ e ||= File.basename(settings.configdata['basepath'])
19
58
  path = get_path(e)[0]
20
59
  if path
21
60
  @base = get_base(path)
22
61
  @base_name = @base.gsub(/\//,'')
23
- get_config(path)
62
+ get_config(path, cached_params(e, node))
24
63
  end
25
64
  end
65
+
66
+ def cached_params(base, node)
67
+ if node
68
+ cache = Hieraviz::Facts.new settings.configdata['tmpdir'], base, node, get_username
69
+ if cache.exist?
70
+ return cache.read
71
+ end
72
+ end
73
+ {}
74
+ end
75
+
26
76
  def prepare_params(e)
27
- e = File.basename(settings.configdata['basepath']) unless e
77
+ e ||= File.basename(settings.configdata['basepath'])
28
78
  path = get_path(e)[0]
29
79
  if path
30
80
  settings.configdata['basepath'] = path
31
81
  settings.configdata
32
82
  end
33
83
  end
84
+
34
85
  def get_path(path)
35
86
  if settings.basepaths
36
87
  settings.basepaths.select do |p|
@@ -40,21 +91,29 @@ module HieravizApp
40
91
  [ settings.configdata['basepath'] ]
41
92
  end
42
93
  end
43
- def get_config(path)
94
+
95
+ def get_config(path, extra)
96
+ args = { config: Hieraviz::Config.configfile }
44
97
  if path
45
- Hieracles::Config.new({
46
- config: Hieraviz::Config.configfile,
47
- basepath: path
48
- })
49
- else
50
- Hieracles::Config.new({
51
- config: Hieraviz::Config.configfile
52
- })
53
- end
98
+ args[:basepath] = path
99
+ end
100
+ if extra.length > 0
101
+ args[:params] = format_params(extra)
102
+ end
103
+ Hieracles::Config.new args
54
104
  end
105
+
55
106
  def get_base(path)
56
107
  "/#{File.basename(path)}"
57
108
  end
109
+
110
+ def format_params(params)
111
+ params.reduce([]) do |a, (k, v)|
112
+ a << "#{k}=#{v}"
113
+ a
114
+ end.join(',')
115
+ end
116
+
58
117
  end
59
118
 
60
119
  end
@@ -171,7 +171,7 @@ input {
171
171
  font-size: 1.2em;
172
172
  line-height: 1.4em;
173
173
  height: 1.4em;
174
- width: 100%;
174
+ width: 330px;
175
175
  position: fixed;
176
176
  }
177
177
  .side .filter input {
@@ -198,8 +198,14 @@ input {
198
198
  .side ul li.focus {
199
199
  background-color: #fff;
200
200
  }
201
-
202
- /* ----- Meat ---- */
201
+ .side ul li.none {
202
+ color: #999;
203
+ }
204
+ .side ul li .count {
205
+ float: right;
206
+ font-family: monospace;
207
+ }
208
+ /* ----- Meat ---- */
203
209
  .meat {
204
210
  border: 2px solid #999;
205
211
  background-color: #fff;
@@ -271,6 +277,7 @@ input {
271
277
  }
272
278
  .meat .rows {
273
279
  margin-top: 3.8em;
280
+ margin-right: 330px;
274
281
  }
275
282
  .meat .row {
276
283
  word-wrap: break-word;
@@ -296,8 +303,9 @@ input {
296
303
  }
297
304
  .meat .row .value {
298
305
  font-family: monospace;
299
- padding: .1em 1em .6em;
306
+ padding: .1em 1em .4em;
300
307
  margin: 0;
308
+ margin-bottom: .2em;
301
309
  }
302
310
  .meat .row:hover {
303
311
  background-color: #f3f3de;
@@ -308,12 +316,95 @@ input {
308
316
  .meat .row:hover .data {
309
317
  background-color: #dd6;
310
318
  }
311
- .meat.farms div {
319
+ .meat.farms .node {
312
320
  padding: .5em 1em;
313
321
  }
314
- .meat.farms div:hover {
322
+ .meat.farms .node:hover {
315
323
  background-color: #f3f3de;
316
324
  }
325
+ .meat .hierarchy {
326
+ margin-top: 3.8em;
327
+ background-color: #ccc;
328
+ position: fixed;
329
+ display: inline-block;
330
+ float: right;
331
+ width: 330px;
332
+ right: 0;
333
+ height: 80%;
334
+ overflow-y: auto;
335
+ overflow-x: hidden;
336
+ }
337
+ .meat .hierarchy .hierafiles {
338
+ padding: 1em;
339
+ font-family: monospace;
340
+ }
341
+ .meat .hierarchy .hierafiles div {
342
+ padding: .2em 0;
343
+ }
344
+ .meat .hierarchy .nodeinfo {
345
+ padding: 1em;
346
+ }
347
+ .meat .hierarchy .nodeinfo .var {
348
+ padding: .2em 0;
349
+ }
350
+ .meat .hierarchy .nodeinfo .label {
351
+ padding: 0 .5em;
352
+ }
353
+ .meat .hierarchy .nodeinfo input {
354
+ width: 100%;
355
+ padding: .2em .5em;
356
+ }
357
+ .meat .hierarchy .factinfo {
358
+ padding: 1em;
359
+ }
360
+ .meat .hierarchy .factinfo .var {
361
+ padding: .2em 0;
362
+ }
363
+ .meat .hierarchy .factinfo .label {
364
+ padding: 0 .5em;
365
+ }
366
+ .meat .hierarchy .factinfo .label i {
367
+ font-size: .8em;
368
+ color: #666;
369
+ }
370
+ .meat .hierarchy .factinfo input {
371
+ width: 100%;
372
+ padding: .2em .5em;
373
+ }
374
+ .meat .hierarchy .updateinfo {
375
+ padding: 0 1em 1em;
376
+ }
377
+ .meat .hierarchy .updateinfo button#updateinfo {
378
+ -webkit-box-shadow: 0px 0px 2px 3px rgba(0,0,0,0.7);
379
+ -moz-box-shadow: 0px 0px 2px 3px rgba(0,0,0,0.7);
380
+ box-shadow: 0px 0px 2px 3px rgba(0,0,0,0.7);
381
+ border-radius: .2em;
382
+ cursor: pointer;
383
+ margin-right: 1em;
384
+ }
385
+
386
+ .meat .hierarchy .updateinfo button {
387
+ -webkit-box-shadow: 0px 0px 2px 3px rgba(0,0,0,0.3);
388
+ -moz-box-shadow: 0px 0px 2px 3px rgba(0,0,0,0.3);
389
+ box-shadow: 0px 0px 2px 3px rgba(0,0,0,0.3);
390
+ border-radius: .2em;
391
+ cursor: pointer;
392
+ margin-right: 1em;
393
+ }
394
+
395
+ .meat .hierarchy .updateinfo button:hover {
396
+ -webkit-box-shadow: 0px 0px 0px 3px rgba(34,168,230,1);
397
+ -moz-box-shadow: 0px 0px 0px 3px rgba(34,168,230,1);
398
+ box-shadow: 0px 0px 0px 3px rgba(34,168,230,1);
399
+ }
400
+ .meat .hierarchy .nodefiles {
401
+ padding: 1em;
402
+ font-family: monospace;
403
+ }
404
+ .meat .hierarchy .nodefiles div {
405
+ padding: .2em 0;
406
+ }
407
+
317
408
  /* ----- info ---- */
318
409
  .meat .info {
319
410
  margin-top: 4.8em;
@@ -18,44 +18,84 @@ function ready(fn) {
18
18
  }
19
19
 
20
20
  ready( () => {
21
- focusNav('farms');
22
-
23
21
  var farms = document.querySelectorAll('li.farm');
24
22
  var meat = document.querySelector('div.meat');
23
+ var base = window.location.pathname.split('/')[1];
24
+ focusNav('farms');
25
+ filterBox(".side .filter input", farms);
26
+
27
+ function restore_url(list) {
28
+ if (window.location.hash != '') {
29
+ var target = window.location.hash.replace(/#/,'');
30
+ var parts = target.split('/');
31
+ Array.prototype.forEach.call(list, (item, i) => {
32
+ if (item.textContent == parts[0]) {
33
+ if (parts[1] != undefined) {
34
+ Farm[parts[1]](parts[0]);
35
+ } else {
36
+ var event = document.createEvent('HTMLEvents');
37
+ event.initEvent('click', true, false);
38
+ item.dispatchEvent(event);
39
+ }
40
+ }
41
+ });
42
+ }
43
+ }
25
44
 
26
- filterBox(".filter input", farms);
27
45
 
28
- function build_list(top, title, array) {
46
+ function build_list(top, title, hash) {
29
47
  window.location.hash = '#'+title;
30
48
  top.innerHTML = "<h3>Farm "+title+"</h3>";
31
- if (array.length > 0)
32
- Array.prototype.forEach.call(array, (item, i) => {
33
- addTo(top, "<div><a href=\"/nodes#"+ item +"\">" +
34
- item +
35
- "</a></div>\n");
49
+ if (Object.keys(hash).length > 0)
50
+ Array.prototype.forEach.call(Object.keys(hash), (item, i) => {
51
+ var node = document.createElement('div');
52
+ node.className = "node";
53
+ top.appendChild(node);
54
+ var node_title = document.createElement('div');
55
+ node_title.innerHTML = '<div><a href="/'+base+'/nodes#'+ item +'">' + item + '</a></div>';
56
+ node.appendChild(node_title);
57
+ Array.prototype.forEach.call(Object.keys(hash[item]), (itemvar, i) => {
58
+ addTo(node, "<div>"+itemvar+": "+hash[item][itemvar]+"</div>")
59
+ });
36
60
  });
37
61
  else
38
62
  addTo(top, "<div>There is no node in this farm.</div>\n");
39
63
  }
40
64
 
41
- Array.prototype.forEach.call(farms, (item, i) => {
42
- item.addEventListener('click', (ev) => {
65
+ function show_error(meat, message) {
66
+ meat.innerHTML = "<div class=\"error\">" + message + "</div>\n";
67
+ }
68
+
69
+
70
+ var Farm = {
71
+ show: function(el) {
43
72
  addClass(meat, 'wait');
44
- el = ev.target;
45
- fetch('/v1/farm/' + el.dataset.item, auth_header()).
73
+ farm = el.dataset.item;
74
+ fetch('/v1/' + base + '/farm/' + farm, auth_header()).
46
75
  then(res => res.json()).
47
76
  then(j => {
48
- build_list(meat, el.dataset.item, j);
49
- Array.prototype.forEach.call(farms, (item, i) => {
50
- removeClass(item, 'focus')
51
- });
52
- addClass(el, 'focus');
53
- update_footer('/v1/farm/' + el.dataset.item);
77
+ if (j.error != undefined) {
78
+ show_error(meat, j['error']);
79
+ } else {
80
+ build_list(meat, farm, j);
81
+ Array.prototype.forEach.call(farms, (item, i) => {
82
+ removeClass(item, 'focus');
83
+ });
84
+ addClass(el, 'focus');
85
+ update_footer('/v1/' + base + '/farm/' + farm);
86
+ }
54
87
  removeClass(meat, 'wait');
55
88
  });
89
+ },
90
+ };
91
+
92
+ Array.prototype.forEach.call(farms, (item, i) => {
93
+ item.addEventListener('click', (ev) => {
94
+ Farm.show(ev.target);
56
95
  });
57
96
  });
58
97
 
98
+ update_footer('/v1/' + base + '/farms');
59
99
  restore_url(farms);
60
100
 
61
101
  });