hieraviz 0.1.0 → 0.1.1
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 +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +2 -0
- data/app/apiv1.rb +18 -12
- data/app/common.rb +45 -0
- data/app/public/css/main.css +91 -4
- data/app/public/js/base-switch.js +27 -0
- data/app/public/js/main.js +10 -14
- data/app/public/js/nodes.js +82 -37
- data/app/views/_head.erb +28 -8
- data/app/views/_layout.erb +6 -3
- data/app/views/farms.erb +2 -2
- data/app/views/logout.erb +1 -1
- data/app/views/modules.erb +2 -2
- data/app/views/nodes.erb +2 -2
- data/app/views/not_found.erb +1 -1
- data/app/views/resources.erb +2 -2
- data/app/views/user.erb +22 -0
- data/app/web.rb +48 -21
- data/lib/hieraviz/config.rb +15 -3
- data/spec/app/web_spec.rb +2 -2
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c977dce78504ac761d4d7d6acd75ad95e873d2a7
|
4
|
+
data.tar.gz: 9afaf6f7186ec5365fe685ff73ad4ce49a401f8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee55dacc40305aec815eb61c1b718aff566fe8d8697f50eccd60dc6f645940ca27632395e1b3f1a11391e1223d003e85f698c551a93d8fd9fb7a1e20df072cbf
|
7
|
+
data.tar.gz: 80e725f5a210c00e2e17b56ec50b1497dfe736292dbc9a8c0c1e70d3e1da69a9082cc5f0ddb097c4d15e3d191913af229c1980702dd376c0b8713c61e4130d73
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -11,6 +11,8 @@ Hieraviz
|
|
11
11
|
|
12
12
|
Hieraviz is a simple web application for accessing Puppet development code and production data in a unified interface. Its main goal is to enable a better visibility on the Puppet architecture for more actors to be able to interact with it.
|
13
13
|
|
14
|
+

|
15
|
+
|
14
16
|
It's currently in very early stages of development, use at your own risk.
|
15
17
|
|
16
18
|
Installation
|
data/app/apiv1.rb
CHANGED
@@ -31,38 +31,44 @@ module HieravizApp
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
get
|
34
|
+
get %r{^/?([-_\.a-zA-Z0-9]+)?/nodes} do |base|
|
35
35
|
check_authorization
|
36
|
-
|
36
|
+
hieracles_config = prepare_config(base)
|
37
|
+
json Hieracles::Registry.nodes(hieracles_config)
|
37
38
|
end
|
38
39
|
|
39
|
-
get
|
40
|
+
get %r{^/?([-_\.a-zA-Z0-9]+)?/node/([-_\.a-zA-Z0-9]+)/info} do |base, node|
|
40
41
|
check_authorization
|
41
|
-
|
42
|
+
hieracles_config = prepare_config(base)
|
43
|
+
node = Hieracles::Node.new(node, hieracles_config)
|
42
44
|
json node.info
|
43
45
|
end
|
44
46
|
|
45
|
-
get
|
47
|
+
get %r{^/?([-_\.a-zA-Z0-9]+)?/node/([-_\.a-zA-Z0-9]+)/params} do |base, node|
|
46
48
|
check_authorization
|
47
|
-
|
49
|
+
hieracles_config = prepare_config(base)
|
50
|
+
node = Hieracles::Node.new(node, hieracles_config)
|
48
51
|
json node.params
|
49
52
|
end
|
50
53
|
|
51
|
-
get
|
54
|
+
get %r{^/?([-_\.a-zA-Z0-9]+)?/node/([-_\.a-zA-Z0-9]+)/allparams} do |base, node|
|
52
55
|
check_authorization
|
53
|
-
|
56
|
+
hieracles_config = prepare_config(base)
|
57
|
+
node = Hieracles::Node.new(node, hieracles_config)
|
54
58
|
json node.params(false)
|
55
59
|
end
|
56
60
|
|
57
|
-
get
|
61
|
+
get %r{^/?([-_\.a-zA-Z0-9]+)?/node/([-_\.a-zA-Z0-9]+)$} do |base, node|
|
58
62
|
check_authorization
|
59
|
-
|
63
|
+
hieracles_config = prepare_config(base)
|
64
|
+
node = Hieracles::Node.new(node, hieracles_config)
|
60
65
|
json node.params
|
61
66
|
end
|
62
67
|
|
63
|
-
get
|
68
|
+
get %r{^/?([-_\.a-zA-Z0-9]+)?/farms} do |base|
|
64
69
|
check_authorization
|
65
|
-
|
70
|
+
hieracles_config = prepare_config(base)
|
71
|
+
json Hieracles::Registry.farms(hieracles_config)
|
66
72
|
end
|
67
73
|
|
68
74
|
# get '/farm/:n' do |farm|
|
data/app/common.rb
CHANGED
@@ -8,9 +8,54 @@ module HieravizApp
|
|
8
8
|
set :app_name, 'HieraViz'
|
9
9
|
set :configdata, Hieraviz::Config.load
|
10
10
|
set :config, Hieracles::Config.new({ config: Hieraviz::Config.configfile })
|
11
|
+
set :basepaths, Hieraviz::Config.basepaths
|
11
12
|
enable :session
|
12
13
|
enable :logging
|
13
14
|
end
|
14
15
|
|
16
|
+
helpers do
|
17
|
+
def prepare_config(e)
|
18
|
+
e = File.basename(settings.configdata['basepath']) unless e
|
19
|
+
path = get_path(e)[0]
|
20
|
+
if path
|
21
|
+
@base = get_base(path)
|
22
|
+
@base_name = @base.gsub(/\//,'')
|
23
|
+
get_config(path)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
def prepare_params(e)
|
27
|
+
e = File.basename(settings.configdata['basepath']) unless e
|
28
|
+
path = get_path(e)[0]
|
29
|
+
if path
|
30
|
+
settings.configdata['basepath'] = path
|
31
|
+
settings.configdata
|
32
|
+
end
|
33
|
+
end
|
34
|
+
def get_path(path)
|
35
|
+
if settings.basepaths
|
36
|
+
settings.basepaths.select do |p|
|
37
|
+
path == File.basename(p)
|
38
|
+
end
|
39
|
+
else
|
40
|
+
[ settings.configdata['basepath'] ]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
def get_config(path)
|
44
|
+
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
|
54
|
+
end
|
55
|
+
def get_base(path)
|
56
|
+
"/#{File.basename(path)}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
15
60
|
end
|
16
61
|
end
|
data/app/public/css/main.css
CHANGED
@@ -41,11 +41,53 @@ input {
|
|
41
41
|
line-height: .5em;
|
42
42
|
margin-right: 1em;
|
43
43
|
}
|
44
|
-
.head .nav {
|
44
|
+
.head .nav, .head .nav .base {
|
45
45
|
position: relative;
|
46
46
|
float: left;
|
47
47
|
display: inline-block;
|
48
48
|
}
|
49
|
+
|
50
|
+
.head .base .current {
|
51
|
+
position: relative;
|
52
|
+
color: #fff;
|
53
|
+
background-color: #666;
|
54
|
+
padding: .5em 1em;
|
55
|
+
border-radius: .2em;
|
56
|
+
font-weight: bold;
|
57
|
+
margin-right: 1em;
|
58
|
+
cursor: pointer;
|
59
|
+
}
|
60
|
+
.head .base .all {
|
61
|
+
position: absolute;
|
62
|
+
display: none;
|
63
|
+
background-color: #fff;
|
64
|
+
width: auto;
|
65
|
+
overflow-x: visible;
|
66
|
+
margin-top: 1em;
|
67
|
+
border: 1px solid #666;
|
68
|
+
}
|
69
|
+
.head .base .all.focus {
|
70
|
+
display: block;
|
71
|
+
}
|
72
|
+
.head .base .all .filter {
|
73
|
+
margin: 0;
|
74
|
+
background-color: #999;
|
75
|
+
font-size: 1.2em;
|
76
|
+
}
|
77
|
+
.head .base .all .filter input {
|
78
|
+
width: 100%;
|
79
|
+
margin-bottom: .1em;
|
80
|
+
padding: .1em 1em;
|
81
|
+
}
|
82
|
+
.head .base .all .select {
|
83
|
+
padding: .2em 1em;
|
84
|
+
color: #666;
|
85
|
+
cursor: pointer;
|
86
|
+
}
|
87
|
+
.head .base .all .select:hover {
|
88
|
+
color: #000;
|
89
|
+
background-color: #ddd;
|
90
|
+
}
|
49
91
|
.head .nav a {
|
50
92
|
position: relative;
|
51
93
|
color: #fff;
|
@@ -62,12 +104,18 @@ input {
|
|
62
104
|
background-color: #fff;
|
63
105
|
color: #000;
|
64
106
|
}
|
107
|
+
.head .base {
|
108
|
+
position: relative;
|
109
|
+
float: right;
|
110
|
+
display: inline-block;
|
111
|
+
margin-left: 2em;
|
112
|
+
}
|
65
113
|
.head .auth {
|
66
114
|
position: relative;
|
67
115
|
display: inline-block;
|
68
116
|
float: right;
|
69
117
|
}
|
70
|
-
.head .auth a {
|
118
|
+
.head .auth a.link {
|
71
119
|
color: #fff;
|
72
120
|
padding: .5em 1em;
|
73
121
|
border-radius: .2em;
|
@@ -76,7 +124,7 @@ input {
|
|
76
124
|
border-radius: .2em;
|
77
125
|
cursor: pointer;
|
78
126
|
}
|
79
|
-
.head .auth a:hover {
|
127
|
+
.head .auth a.link:hover {
|
80
128
|
background-color: #fff;
|
81
129
|
color: #000;
|
82
130
|
}
|
@@ -86,7 +134,11 @@ input {
|
|
86
134
|
}
|
87
135
|
.head .auth .username {
|
88
136
|
display: inline-block;
|
89
|
-
margin-right:
|
137
|
+
margin-right: .2em;
|
138
|
+
}
|
139
|
+
.head .auth .username .link {
|
140
|
+
color: #fff;
|
141
|
+
background-color: #999;
|
90
142
|
}
|
91
143
|
/* ----- Content ---- */
|
92
144
|
.content {
|
@@ -100,6 +152,9 @@ input {
|
|
100
152
|
.error {
|
101
153
|
padding: 2em;
|
102
154
|
}
|
155
|
+
.info tr td {
|
156
|
+
padding-right: 2em;
|
157
|
+
}
|
103
158
|
/* ----- Sidebar ---- */
|
104
159
|
.side {
|
105
160
|
background-color: #eee;
|
@@ -114,6 +169,10 @@ input {
|
|
114
169
|
margin: 0;
|
115
170
|
background-color: #999;
|
116
171
|
font-size: 1.2em;
|
172
|
+
line-height: 1.4em;
|
173
|
+
height: 1.4em;
|
174
|
+
width: 100%;
|
175
|
+
position: fixed;
|
117
176
|
}
|
118
177
|
.side .filter input {
|
119
178
|
width: 100%;
|
@@ -123,6 +182,7 @@ input {
|
|
123
182
|
.side ul {
|
124
183
|
margin: 0;
|
125
184
|
padding: 0;
|
185
|
+
margin-top: 1.8em;
|
126
186
|
list-style: none;
|
127
187
|
border-right: 1px solid #ccc;
|
128
188
|
}
|
@@ -191,6 +251,12 @@ input {
|
|
191
251
|
.meat .nodenav span.focus {
|
192
252
|
background-color: #fff;
|
193
253
|
}
|
254
|
+
.meat .filter {
|
255
|
+
height: 4em;
|
256
|
+
position: fixed;
|
257
|
+
left: 330px;
|
258
|
+
right: 0;
|
259
|
+
}
|
194
260
|
.meat .paramfilter {
|
195
261
|
margin: 0;
|
196
262
|
padding: 0 1em;
|
@@ -203,6 +269,9 @@ input {
|
|
203
269
|
margin-bottom: .1em;
|
204
270
|
padding: .1em 1em;
|
205
271
|
}
|
272
|
+
.meat .rows {
|
273
|
+
margin-top: 3.8em;
|
274
|
+
}
|
206
275
|
.meat .row {
|
207
276
|
word-wrap: break-word;
|
208
277
|
}
|
@@ -245,6 +314,24 @@ input {
|
|
245
314
|
.meat.farms div:hover {
|
246
315
|
background-color: #f3f3de;
|
247
316
|
}
|
317
|
+
/* ----- info ---- */
|
318
|
+
.meat .info {
|
319
|
+
margin-top: 4.8em;
|
320
|
+
display: table;
|
321
|
+
}
|
322
|
+
.meat .info .row {
|
323
|
+
display: table-row;
|
324
|
+
}
|
325
|
+
.meat .info .row .infokey {
|
326
|
+
display: table-cell;
|
327
|
+
padding: .1em 1em;
|
328
|
+
text-align: right;
|
329
|
+
}
|
330
|
+
.meat .info .row .infovalue {
|
331
|
+
display: table-cell;
|
332
|
+
font-family: monospace;
|
333
|
+
padding: .1em 1em;
|
334
|
+
}
|
248
335
|
/* ----- Foot ---- */
|
249
336
|
.foot {
|
250
337
|
padding: 1em;
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
ready( () => {
|
3
|
+
var bases = document.querySelectorAll('.base .all .select');
|
4
|
+
var button = document.querySelector(".base .current");
|
5
|
+
var menu = document.querySelector(".base .all");
|
6
|
+
var menuvisible = false;
|
7
|
+
filterBox(".base .all .filter input", bases);
|
8
|
+
|
9
|
+
button.addEventListener('click', (ev) => {
|
10
|
+
if (menuvisible) {
|
11
|
+
removeClass(menu, "focus");
|
12
|
+
} else {
|
13
|
+
addClass(menu, "focus");
|
14
|
+
}
|
15
|
+
menuvisible = !menuvisible;
|
16
|
+
});
|
17
|
+
|
18
|
+
/* declaration of events for the bases menu */
|
19
|
+
Array.prototype.forEach.call(bases, (item, i) => {
|
20
|
+
item.addEventListener('click', (ev) => {
|
21
|
+
var url = window.location;
|
22
|
+
base = ev.target.textContent;
|
23
|
+
url.pathname = url.pathname.replace(/^\/[^\/]+/,"/"+base);
|
24
|
+
});
|
25
|
+
});
|
26
|
+
|
27
|
+
});
|
data/app/public/js/main.js
CHANGED
@@ -27,7 +27,7 @@ function make_base_auth(user, password) {
|
|
27
27
|
}
|
28
28
|
|
29
29
|
function addClass(el, className) {
|
30
|
-
if (el.classList)
|
30
|
+
if (el.classList != null)
|
31
31
|
el.classList.add(className);
|
32
32
|
else
|
33
33
|
el.className += ' ' + className;
|
@@ -84,19 +84,6 @@ function end_wait(meat) {
|
|
84
84
|
removeClass(meat, 'wait');
|
85
85
|
}
|
86
86
|
|
87
|
-
function restore_url(list) {
|
88
|
-
if (window.location.hash != '') {
|
89
|
-
var target = window.location.hash.replace(/#/,'');
|
90
|
-
Array.prototype.forEach.call(list, (item, i) => {
|
91
|
-
if (item.textContent == target) {
|
92
|
-
var event = document.createEvent('HTMLEvents');
|
93
|
-
event.initEvent('click', true, false);
|
94
|
-
item.dispatchEvent(event);
|
95
|
-
}
|
96
|
-
});
|
97
|
-
}
|
98
|
-
}
|
99
|
-
|
100
87
|
function update_footer(path) {
|
101
88
|
var debug = document.querySelector('.foot .debug');
|
102
89
|
debug.innerHTML = "curl -s http://" + window.location.host + path + " | jq '.'";
|
@@ -111,6 +98,8 @@ function auth_header() {
|
|
111
98
|
|
112
99
|
ready( () => {
|
113
100
|
|
101
|
+
var meat = document.querySelector('div.meat');
|
102
|
+
|
114
103
|
var flash = document.querySelectorAll('div.flash');
|
115
104
|
Array.prototype.forEach.call(flash, (item, i) => {
|
116
105
|
item.addEventListener('click', (ev) => {
|
@@ -118,4 +107,11 @@ ready( () => {
|
|
118
107
|
});
|
119
108
|
});
|
120
109
|
|
110
|
+
var login = document.querySelector('#login');
|
111
|
+
if (login != null) {
|
112
|
+
login.addEventListener('click', (ev) => {
|
113
|
+
start_wait(meat);
|
114
|
+
});
|
115
|
+
}
|
116
|
+
|
121
117
|
});
|
data/app/public/js/nodes.js
CHANGED
@@ -13,8 +13,28 @@ ready( () => {
|
|
13
13
|
|
14
14
|
var meat = document.querySelector('div.meat');
|
15
15
|
var nodes = document.querySelectorAll('li.node');
|
16
|
+
var base = window.location.pathname.split('/')[1];
|
16
17
|
focusNav('nodes');
|
17
|
-
filterBox(".filter input", nodes);
|
18
|
+
filterBox(".side .filter input", nodes);
|
19
|
+
|
20
|
+
function restore_url(list) {
|
21
|
+
if (window.location.hash != '') {
|
22
|
+
var target = window.location.hash.replace(/#/,'');
|
23
|
+
var parts = target.split('/');
|
24
|
+
Array.prototype.forEach.call(list, (item, i) => {
|
25
|
+
if (item.textContent == parts[0]) {
|
26
|
+
if (parts[1] != undefined) {
|
27
|
+
Node[parts[1]](parts[0]);
|
28
|
+
} else {
|
29
|
+
var event = document.createEvent('HTMLEvents');
|
30
|
+
event.initEvent('click', true, false);
|
31
|
+
item.dispatchEvent(event);
|
32
|
+
}
|
33
|
+
}
|
34
|
+
});
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
18
38
|
|
19
39
|
function build_line(top, file, key, value, overriden) {
|
20
40
|
if (overriden === true) {
|
@@ -46,25 +66,45 @@ ready( () => {
|
|
46
66
|
}
|
47
67
|
|
48
68
|
function build_top(title) {
|
49
|
-
meat.innerHTML = "
|
50
|
-
addTo(meat, "<div class=\"
|
69
|
+
meat.innerHTML = "";
|
70
|
+
addTo(meat, "<div class=\"filter\">" +
|
71
|
+
"<h3>Node "+title+"</h3>" +
|
72
|
+
"<div class=\"nodenav\">" +
|
51
73
|
"<span class=\"showinfo\" data-item=\""+title+"\">Info</span>" +
|
52
74
|
"<span class=\"showparams\" data-item=\""+title+"\">Params</span>" +
|
53
75
|
"<span class=\"showallparams\" data-item=\""+title+"\">AllParams</span>" +
|
54
|
-
"</div>"
|
55
|
-
addTo(meat, "<div class=\"paramfilter\">" +
|
76
|
+
"</div><div class=\"paramfilter\">" +
|
56
77
|
"<input type=\"text\" name=\"paramfilter\" />" +
|
57
|
-
"</div>");
|
78
|
+
"</div></div>");
|
58
79
|
}
|
59
80
|
|
60
81
|
function build_info(top, title, hash) {
|
61
|
-
|
82
|
+
if (Object.keys(hash).length > 0) {
|
83
|
+
var wrapper = document.createElement('div');
|
84
|
+
wrapper.className = 'rows info';
|
85
|
+
top.appendChild(wrapper);
|
86
|
+
Array.prototype.forEach.call(Object.keys(hash), (item, k) => {
|
87
|
+
console.log(item);
|
88
|
+
addTo(wrapper, "<div class=\"row\">" +
|
89
|
+
"<span class=\"infokey\">" + item + "</span>" +
|
90
|
+
"<span class=\"infovalue\">" + JSON.stringify(hash[item], null, 2) + "</span>" +
|
91
|
+
"</div");
|
92
|
+
});
|
93
|
+
var rows = document.querySelectorAll('div.row');
|
94
|
+
filterBox(".paramfilter input", rows);
|
95
|
+
} else {
|
96
|
+
addTo(top, "<div>There is no params in this node.</div>\n");
|
97
|
+
}
|
98
|
+
window.location.hash = '#' + title +'/info';
|
62
99
|
}
|
63
100
|
|
64
101
|
function build_params(top, title, hash) {
|
65
102
|
if (Object.keys(hash).length > 0) {
|
103
|
+
var wrapper = document.createElement('div');
|
104
|
+
wrapper.className = 'rows';
|
105
|
+
top.appendChild(wrapper);
|
66
106
|
Array.prototype.forEach.call(Object.keys(hash), (item, k) => {
|
67
|
-
build_row(
|
107
|
+
build_row(wrapper, item, hash[item]);
|
68
108
|
});
|
69
109
|
var rows = document.querySelectorAll('div.row');
|
70
110
|
filterBox(".paramfilter input", rows);
|
@@ -79,15 +119,9 @@ ready( () => {
|
|
79
119
|
var nodelinks = document.querySelectorAll('div.nodenav span');
|
80
120
|
Array.prototype.forEach.call(nodelinks, (item, i) => {
|
81
121
|
item.addEventListener('click', (ev) => {
|
82
|
-
start_wait();
|
83
122
|
el = ev.target;
|
84
123
|
action = el.textContent.toLowerCase();
|
85
|
-
|
86
|
-
then(res => res.json()).
|
87
|
-
then(j => {
|
88
|
-
focus_on(nodelinks, el);
|
89
|
-
end_wait();
|
90
|
-
});
|
124
|
+
Node[action](el.dataset.item);
|
91
125
|
});
|
92
126
|
});
|
93
127
|
}
|
@@ -97,49 +131,60 @@ ready( () => {
|
|
97
131
|
}
|
98
132
|
|
99
133
|
var Node = {
|
100
|
-
params: function(
|
134
|
+
params: function(node) {
|
101
135
|
start_wait(meat);
|
102
|
-
|
103
|
-
fetch('/v1/node/' + title, auth_header()).
|
136
|
+
fetch('/v1/' + base + '/node/' + node, auth_header()).
|
104
137
|
then(res => res.json()).
|
105
138
|
then(j => {
|
106
139
|
console.log(auth_header().headers.getAll('x-auth'));
|
140
|
+
build_top(node);
|
107
141
|
if (j.error != undefined) {
|
108
142
|
show_error(meat, j['error']);
|
109
143
|
} else {
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
144
|
+
build_params(meat, node, j);
|
145
|
+
rebuild_nav(node);
|
146
|
+
update_footer('/v1/' + base + '/node/' + node);
|
147
|
+
but = document.querySelector('.showparams');
|
148
|
+
addClass(but, 'focus');
|
114
149
|
}
|
115
150
|
end_wait(meat);
|
116
151
|
});
|
117
152
|
},
|
118
153
|
|
119
|
-
info: function(
|
154
|
+
info: function(node) {
|
120
155
|
start_wait(meat);
|
121
|
-
|
122
|
-
fetch('/v1/node/' + title + '/info', auth_header()).
|
156
|
+
fetch('/v1/' + base + '/node/' + node + '/info', auth_header()).
|
123
157
|
then(res => res.json()).
|
124
158
|
then(j => {
|
125
|
-
build_top(
|
126
|
-
|
127
|
-
|
128
|
-
|
159
|
+
build_top(node);
|
160
|
+
if (j.error != undefined) {
|
161
|
+
show_error(meat, j['error']);
|
162
|
+
} else {
|
163
|
+
build_info(meat, node, j);
|
164
|
+
rebuild_nav(node);
|
165
|
+
update_footer('/v1/' + base + '/node/' + node + '/info');
|
166
|
+
but = document.querySelector('.showinfo');
|
167
|
+
addClass(but, 'focus');
|
168
|
+
}
|
129
169
|
end_wait(meat);
|
130
170
|
});
|
131
171
|
},
|
132
172
|
|
133
|
-
allparams: function(
|
173
|
+
allparams: function(node) {
|
134
174
|
start_wait(meat);
|
135
|
-
|
136
|
-
fetch('/v1/node/' + title + '/all', auth_header()).
|
175
|
+
fetch('/v1/' + base + '/node/' + node + '/allparams', auth_header()).
|
137
176
|
then(res => res.json()).
|
138
177
|
then(j => {
|
139
|
-
build_top(
|
140
|
-
|
141
|
-
|
142
|
-
|
178
|
+
build_top(node);
|
179
|
+
if (j.error != undefined) {
|
180
|
+
show_error(meat, j['error']);
|
181
|
+
} else {
|
182
|
+
build_params(meat, node, j);
|
183
|
+
rebuild_nav(node);
|
184
|
+
update_footer('/v1/' + base + '/node/' + node + '/allparams');
|
185
|
+
but = document.querySelector('.showallparams');
|
186
|
+
addClass(but, 'focus');
|
187
|
+
}
|
143
188
|
end_wait(meat);
|
144
189
|
});
|
145
190
|
},
|
@@ -148,7 +193,7 @@ ready( () => {
|
|
148
193
|
/* declaration of events for the nodes menu */
|
149
194
|
Array.prototype.forEach.call(nodes, (item, i) => {
|
150
195
|
item.addEventListener('click', (ev) => {
|
151
|
-
Node.params(ev.target);
|
196
|
+
Node.params(ev.target.textContent);
|
152
197
|
});
|
153
198
|
});
|
154
199
|
|
data/app/views/_head.erb
CHANGED
@@ -3,21 +3,41 @@
|
|
3
3
|
<%= settings.app_name %>
|
4
4
|
</a>
|
5
5
|
</div>
|
6
|
-
|
6
|
+
|
7
|
+
<% if session[:access_token] && @username != '' and @base -%>
|
7
8
|
<div class="nav">
|
8
|
-
|
9
|
-
<
|
10
|
-
<
|
11
|
-
<
|
9
|
+
<% if settings.basepaths -%>
|
10
|
+
<div class="base">
|
11
|
+
<span class="current"><%= @base_name %></span>
|
12
|
+
<div class="all">
|
13
|
+
|
14
|
+
<form class="filter">
|
15
|
+
<input type="text" name="filter" />
|
16
|
+
</form>
|
17
|
+
|
18
|
+
<% settings.basepaths.map { |p| File.basename(p) }.each do |e| -%>
|
19
|
+
<div class="select"><%= e %></div>
|
20
|
+
<% end -%>
|
21
|
+
</div>
|
12
22
|
</div>
|
23
|
+
<% end -%>
|
24
|
+
|
25
|
+
<a href="<%= @base %>/nodes" class="nodes">Nodes</a>
|
26
|
+
<a href="<%= @base %>/farms" class="farms">Farms</a>
|
27
|
+
<a href="<%= @base %>/modules" class="modules">Modules</a>
|
28
|
+
<a href="<%= @base %>/resources" class="resources">Resources</a>
|
29
|
+
</div>
|
30
|
+
<% end -%>
|
31
|
+
|
32
|
+
<% if session[:access_token] && @username != '' -%>
|
13
33
|
<div class="auth">
|
14
34
|
<div class="username">
|
15
|
-
identified as <
|
35
|
+
identified as <a href="<%= @base %>/user" class="link"><%= @username %></a>
|
16
36
|
</div>
|
17
|
-
<a href="/logout" id="logout">Logout</a>
|
37
|
+
<a href="/logout" class="link" id="logout">Logout</a>
|
18
38
|
</div>
|
19
39
|
<% else -%>
|
20
40
|
<div class="auth">
|
21
|
-
<a href="/login" id="login">Connect</a>
|
41
|
+
<a href="/login" class="link" id="login">Connect</a>
|
22
42
|
</div>
|
23
43
|
<% end -%>
|
data/app/views/_layout.erb
CHANGED
@@ -4,9 +4,12 @@
|
|
4
4
|
<title>Hieraviz
|
5
5
|
<%= @title if @title %>
|
6
6
|
</title>
|
7
|
-
<link href="css/main.css" rel="stylesheet" type="text/css">
|
8
|
-
<script src="js/fetch.js"></script>
|
9
|
-
<script src="js/main.js"></script>
|
7
|
+
<link href="/css/main.css" rel="stylesheet" type="text/css">
|
8
|
+
<script src="/js/fetch.js"></script>
|
9
|
+
<script src="/js/main.js"></script>
|
10
|
+
<% if settings.basepaths -%>
|
11
|
+
<script src="/js/base-switch.js"></script>
|
12
|
+
<% end -%>
|
10
13
|
<% if session['access_token'] -%>
|
11
14
|
<script>var session_key = "<%= session['access_token'] %>";</script>
|
12
15
|
<% end -%>
|
data/app/views/farms.erb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
<% content_for :more_js do %>
|
2
|
-
<script src="js/farms.js"></script>
|
2
|
+
<script src="/js/farms.js"></script>
|
3
3
|
<% end %>
|
4
4
|
|
5
5
|
<div class="side">
|
@@ -8,7 +8,7 @@
|
|
8
8
|
</form>
|
9
9
|
<ul>
|
10
10
|
<% @farms.each do |farm| %>
|
11
|
-
<li class="farm" data-item="<%= farm %>"><%= farm %></li>
|
11
|
+
<li class="farm" data-env="<%= @base %>" data-item="<%= farm %>"><%= farm %></li>
|
12
12
|
<% end %>
|
13
13
|
</ul>
|
14
14
|
</div>
|
data/app/views/logout.erb
CHANGED
data/app/views/modules.erb
CHANGED
data/app/views/nodes.erb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
<% content_for :more_js do %>
|
2
|
-
<script src="js/nodes.js"></script>
|
2
|
+
<script src="/js/nodes.js"></script>
|
3
3
|
<% end %>
|
4
4
|
|
5
5
|
<div class="side">
|
@@ -8,7 +8,7 @@
|
|
8
8
|
</form>
|
9
9
|
<ul>
|
10
10
|
<% @nodes.each do |node| %>
|
11
|
-
<li class="node" data-item="<%= node %>"><%= node %></li>
|
11
|
+
<li class="node" data-env="<%= @base %>" data-item="<%= node %>"><%= node %></li>
|
12
12
|
<% end %>
|
13
13
|
</ul>
|
14
14
|
</div>
|
data/app/views/not_found.erb
CHANGED
data/app/views/resources.erb
CHANGED
data/app/views/user.erb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
<% content_for :more_js do %>
|
2
|
+
<script>
|
3
|
+
ready( () => {
|
4
|
+
var debug = document.querySelector('.foot .debug');
|
5
|
+
debug.innerHTML = "export HIERAVIZ_KEY=\"<%= session['access_token'] %>\"";
|
6
|
+
});
|
7
|
+
</script>
|
8
|
+
<% end %>
|
9
|
+
<div class="meat text">
|
10
|
+
<h1>User information</h1>
|
11
|
+
<% if @userinfo['avatar_url'] -%>
|
12
|
+
<img src="<%= @userinfo['avatar_url'] %>" align="left" style="margin-top:.4em;margin-right:1em;" />
|
13
|
+
<% end -%>
|
14
|
+
<table class="info">
|
15
|
+
<% @userinfo.each do |k,v| -%>
|
16
|
+
<% if %w(username id created_at email).include? k -%>
|
17
|
+
<tr><td><%= k %></td><td><%= v %></td></tr>
|
18
|
+
<% end -%>
|
19
|
+
<% end -%>
|
20
|
+
<tr><td>Session Key</td><td><%= session['access_token'] %></td></tr>
|
21
|
+
</table>
|
22
|
+
</div>
|
data/app/web.rb
CHANGED
@@ -44,6 +44,9 @@ module HieravizApp
|
|
44
44
|
def get_username
|
45
45
|
settings.configdata['http_auth']['username']
|
46
46
|
end
|
47
|
+
def get_userinfo
|
48
|
+
{ 'username' => settings.configdata['http_auth']['username'] }
|
49
|
+
end
|
47
50
|
def check_authorization
|
48
51
|
true
|
49
52
|
end
|
@@ -65,6 +68,10 @@ module HieravizApp
|
|
65
68
|
end
|
66
69
|
end
|
67
70
|
|
71
|
+
def get_userinfo
|
72
|
+
Hieraviz::Store.get(session['access_token'], settings.configdata['session_renew'])
|
73
|
+
end
|
74
|
+
|
68
75
|
def check_authorization
|
69
76
|
if !session['access_token']
|
70
77
|
redirect settings.oauth.login_url(request)
|
@@ -83,7 +90,7 @@ module HieravizApp
|
|
83
90
|
end
|
84
91
|
end
|
85
92
|
end
|
86
|
-
|
93
|
+
|
87
94
|
get '/login' do
|
88
95
|
redirect settings.oauth.login_url(request)
|
89
96
|
end
|
@@ -104,55 +111,75 @@ module HieravizApp
|
|
104
111
|
else
|
105
112
|
end
|
106
113
|
|
107
|
-
|
108
114
|
get '/' do
|
109
|
-
|
110
|
-
|
115
|
+
if settings.basepaths
|
116
|
+
redirect "/#{File.basename(settings.configdata['basepath'])}"
|
117
|
+
else
|
118
|
+
@username = get_username
|
119
|
+
hieracles_config = prepare_config(nil)
|
120
|
+
erb :home
|
121
|
+
end
|
111
122
|
end
|
112
123
|
|
113
|
-
get
|
124
|
+
get %r{^/?([-_\.a-zA-Z0-9]+)?/nodes} do |base|
|
114
125
|
@username = check_authorization
|
115
|
-
|
116
|
-
|
126
|
+
hieracles_config = prepare_config(base)
|
127
|
+
@nodes = Hieracles::Registry.nodes(hieracles_config)
|
128
|
+
erb :nodes
|
117
129
|
end
|
118
130
|
|
119
|
-
get
|
131
|
+
get %r{^/?([-_\.a-zA-Z0-9]+)?/farms} do |base|
|
120
132
|
@username = check_authorization
|
121
|
-
|
133
|
+
hieracles_config = prepare_config(base)
|
134
|
+
@farms = Hieracles::Registry.farms(hieracles_config)
|
122
135
|
erb :farms
|
123
136
|
end
|
124
137
|
|
125
|
-
get
|
138
|
+
get %r{^/?([-_\.a-zA-Z0-9]+)?/modules} do |base|
|
126
139
|
@username = check_authorization
|
140
|
+
hieracles_config = prepare_config(base)
|
127
141
|
erb :modules
|
128
142
|
end
|
129
143
|
|
130
|
-
get
|
144
|
+
get %r{^/?([-_\.a-zA-Z0-9]+)?/resources} do |base|
|
131
145
|
@username = check_authorization
|
146
|
+
hieracles_config = prepare_config(base)
|
132
147
|
erb :resources
|
133
148
|
end
|
134
149
|
|
150
|
+
get %r{^/?([-_\.a-zA-Z0-9]+)?/user} do |base|
|
151
|
+
@username = check_authorization
|
152
|
+
hieracles_config = prepare_config(base)
|
153
|
+
if session[:access_token]
|
154
|
+
@userinfo = get_userinfo
|
155
|
+
else
|
156
|
+
@userinfo = {}
|
157
|
+
end
|
158
|
+
erb :user
|
159
|
+
end
|
160
|
+
|
161
|
+
get %r{^/([-_\.a-zA-Z0-9]+)$} do |base|
|
162
|
+
@username = get_username
|
163
|
+
hieracles_config = prepare_config(base)
|
164
|
+
erb :home
|
165
|
+
end
|
166
|
+
|
135
167
|
# debug pages --------------------
|
136
168
|
# get '/store' do
|
137
169
|
# # Hieraviz::Store.set 'woot', 'nada'
|
138
170
|
# erb :store
|
139
171
|
# end
|
140
|
-
|
141
|
-
# get '/user' do
|
142
|
-
# if session[:access_token]
|
143
|
-
# @data = settings.oauth.user_info(session[:access_token])
|
144
|
-
# else
|
145
|
-
# @data = 'nada'
|
146
|
-
# end
|
147
|
-
# erb :data
|
148
|
-
# end
|
149
|
-
|
150
172
|
# error 401 do
|
151
173
|
# 'Access forbidden'
|
152
174
|
# end
|
175
|
+
# get '/paths' do
|
176
|
+
# @data = settings.basepaths.map { |p| File.basename(p) }
|
177
|
+
# erb :data
|
178
|
+
# end
|
153
179
|
# debug pages --------------------
|
154
180
|
|
155
181
|
not_found do
|
182
|
+
@username = get_username
|
156
183
|
erb :not_found, layout: :_layout
|
157
184
|
end
|
158
185
|
|
data/lib/hieraviz/config.rb
CHANGED
@@ -7,14 +7,26 @@ module Hieraviz
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def configfile
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
root_path(ENV['HIERAVIZ_CONFIG_FILE'] || File.join("config", "hieraviz.yml"))
|
11
|
+
end
|
12
|
+
|
13
|
+
def basepaths
|
14
|
+
if @_config && @_config['basepath_dir']
|
15
|
+
Dir.glob(root_path(@_config['basepath_dir'])).map { |p| File.expand_path(p) }
|
16
|
+
end
|
13
17
|
end
|
14
18
|
|
15
19
|
def root
|
16
20
|
File.expand_path('../../../', __FILE__)
|
17
21
|
end
|
18
22
|
|
23
|
+
def root_path(path)
|
24
|
+
if path[0] == '/'
|
25
|
+
path
|
26
|
+
else
|
27
|
+
File.join(root, path)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
19
31
|
end
|
20
32
|
end
|
data/spec/app/web_spec.rb
CHANGED
@@ -39,8 +39,8 @@ describe HieravizApp::Web do
|
|
39
39
|
before { get '/resources' }
|
40
40
|
it { expect(last_response.body).to include 'Work In Progress' }
|
41
41
|
end
|
42
|
-
describe "GET /toto" do
|
43
|
-
before { get '/toto' }
|
42
|
+
describe "GET /tata/toto" do
|
43
|
+
before { get '/tata/toto' }
|
44
44
|
it { expect(last_response.status).to eq 404 }
|
45
45
|
it { expect(last_response.body).to include 'Page not found' }
|
46
46
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hieraviz
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mose
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-01-
|
11
|
+
date: 2016-01-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dotenv
|
@@ -225,6 +225,7 @@ files:
|
|
225
225
|
- app/main.rb
|
226
226
|
- app/public/css/main.css
|
227
227
|
- app/public/img/loader.gif
|
228
|
+
- app/public/js/base-switch.js
|
228
229
|
- app/public/js/farms.js
|
229
230
|
- app/public/js/fetch.js
|
230
231
|
- app/public/js/logout.js
|
@@ -244,6 +245,7 @@ files:
|
|
244
245
|
- app/views/not_found.erb
|
245
246
|
- app/views/resources.erb
|
246
247
|
- app/views/store.erb
|
248
|
+
- app/views/user.erb
|
247
249
|
- app/web.rb
|
248
250
|
- bin/hv-ctl
|
249
251
|
- config.ru
|