hieraviz 0.1.1 → 0.1.2

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.
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
  });