oxidized-web 0.13.1 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of oxidized-web might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.github/PULL_REQUEST_TEMPLATE.md +12 -0
- data/.github/dependabot.yml +25 -0
- data/.github/workflows/codeql.yml +76 -0
- data/.github/workflows/ruby.yml +41 -0
- data/.github/workflows/stale.yml +20 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +38 -3
- data/.rubocop_todo.yml +27 -211
- data/CHANGELOG.md +46 -0
- data/README.md +8 -5
- data/Rakefile +49 -5
- data/docs/development.md +182 -0
- data/lib/oxidized/web/public/css/oxidized.css +59 -0
- data/lib/oxidized/web/public/scripts/oxidized.js +1 -48
- data/lib/oxidized/web/public/weblibs/bootstrap-icons.css +2078 -0
- data/lib/oxidized/web/public/weblibs/bootstrap.bundle.js +6314 -0
- data/lib/oxidized/web/public/weblibs/bootstrap.bundle.js.map +1 -0
- data/lib/oxidized/web/public/weblibs/bootstrap.css +12057 -0
- data/lib/oxidized/web/public/weblibs/bootstrap.css.map +1 -0
- data/lib/oxidized/web/public/weblibs/bootstrap.js +4494 -0
- data/lib/oxidized/web/public/weblibs/bootstrap.js.map +1 -0
- data/lib/oxidized/web/public/weblibs/buttons.bootstrap5.css +395 -0
- data/lib/oxidized/web/public/weblibs/buttons.bootstrap5.js +114 -0
- data/lib/oxidized/web/public/weblibs/buttons.colVis.js +256 -0
- data/lib/oxidized/web/public/weblibs/dataTables.bootstrap5.css +517 -0
- data/lib/oxidized/web/public/weblibs/dataTables.bootstrap5.js +122 -0
- data/lib/oxidized/web/public/weblibs/dataTables.buttons.js +2936 -0
- data/lib/oxidized/web/public/weblibs/dataTables.js +13843 -0
- data/lib/oxidized/web/public/weblibs/fonts/bootstrap-icons.woff +0 -0
- data/lib/oxidized/web/public/weblibs/fonts/bootstrap-icons.woff2 +0 -0
- data/lib/oxidized/web/public/weblibs/jquery.js +10716 -0
- data/lib/oxidized/web/version.rb +7 -0
- data/lib/oxidized/web/views/conf_search.haml +14 -13
- data/lib/oxidized/web/views/diffs.haml +5 -5
- data/lib/oxidized/web/views/footer.haml +5 -4
- data/lib/oxidized/web/views/head.haml +21 -7
- data/lib/oxidized/web/views/layout.haml +25 -34
- data/lib/oxidized/web/views/node.haml +10 -8
- data/lib/oxidized/web/views/nodes.haml +45 -35
- data/lib/oxidized/web/views/stats.haml +32 -24
- data/lib/oxidized/web/views/version.haml +8 -6
- data/lib/oxidized/web/views/versions.haml +23 -24
- data/lib/oxidized/web/webapp.rb +117 -113
- data/lib/oxidized/web.rb +10 -7
- data/oxidized-web.gemspec +32 -18
- data/package-lock.json +104 -0
- data/package.json +21 -0
- data/spec/node_spec.rb +99 -0
- data/spec/node_version_spec.rb +102 -0
- data/spec/nodes_spec.rb +57 -0
- data/spec/root_spec.rb +18 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/webapp_spec.rb +28 -0
- metadata +183 -74
- data/lib/oxidized/web/mig.rb +0 -150
- data/lib/oxidized/web/public/css/bootstrap.min.css +0 -5
- data/lib/oxidized/web/public/css/buttons.bootstrap.min.css +0 -1
- data/lib/oxidized/web/public/css/dataTables.bootstrap.css +0 -299
- data/lib/oxidized/web/public/css/dataTables.colVis.css +0 -171
- data/lib/oxidized/web/public/css/oxidized_custom.css +0 -19
- data/lib/oxidized/web/public/fonts/glyphicons-halflings-regular.eot +0 -0
- data/lib/oxidized/web/public/fonts/glyphicons-halflings-regular.svg +0 -229
- data/lib/oxidized/web/public/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/lib/oxidized/web/public/fonts/glyphicons-halflings-regular.woff +0 -0
- data/lib/oxidized/web/public/images/diff_15x17.png +0 -0
- data/lib/oxidized/web/public/images/sort_asc.png +0 -0
- data/lib/oxidized/web/public/images/sort_asc_disabled.png +0 -0
- data/lib/oxidized/web/public/images/sort_both.png +0 -0
- data/lib/oxidized/web/public/images/sort_desc.png +0 -0
- data/lib/oxidized/web/public/images/sort_desc_disabled.png +0 -0
- data/lib/oxidized/web/public/images/versioning_18px.png +0 -0
- data/lib/oxidized/web/public/scripts/bootstrap.min.js +0 -6
- data/lib/oxidized/web/public/scripts/dataTables.bootstrap.js +0 -186
- data/lib/oxidized/web/public/scripts/dataTables.colVis.js +0 -1123
- data/lib/oxidized/web/public/scripts/jquery-2.1.1.min.js +0 -4
- data/lib/oxidized/web/public/scripts/jquery.dataTables.min.js +0 -157
- data/lib/oxidized/web/public/scripts/jquery.min.js +0 -6
- data/lib/oxidized/web/public/scripts/script-migration.js +0 -15
- data/lib/oxidized/web/views/migration.haml +0 -46
- data/lib/oxidized/web/views/sass/oxidized.sass +0 -113
data/spec/node_spec.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe Oxidized::API::WebApp do
|
4
|
+
include Rack::Test::Methods
|
5
|
+
|
6
|
+
def app
|
7
|
+
Oxidized::API::WebApp
|
8
|
+
end
|
9
|
+
|
10
|
+
before do
|
11
|
+
@nodes = mock('Oxidized::Nodes')
|
12
|
+
app.set(:nodes, @nodes)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '/node/fetch/' do
|
16
|
+
it 'gets the latest configuration of a node' do
|
17
|
+
@nodes.expects(:fetch).with('sw42', nil).returns('Configuration of sw42')
|
18
|
+
|
19
|
+
get '/node/fetch/sw42'
|
20
|
+
_(last_response.ok?).must_equal true
|
21
|
+
_(last_response.body).must_equal 'Configuration of sw42'
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'gets the configuration of a node when a group is given' do
|
25
|
+
@nodes.expects(:fetch).with('sw42', 'mygroup').returns('Configuration of sw42')
|
26
|
+
|
27
|
+
get '/node/fetch/mygroup/sw42'
|
28
|
+
_(last_response.ok?).must_equal true
|
29
|
+
_(last_response.body).must_equal 'Configuration of sw42'
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'gets the configuration of a node when a group contains /' do
|
33
|
+
@nodes.expects(:fetch).with('sw42', 'my/group').returns('Configuration of sw42')
|
34
|
+
|
35
|
+
get '/node/fetch/my/group/sw42'
|
36
|
+
_(last_response.ok?).must_equal true
|
37
|
+
_(last_response.body).must_equal 'Configuration of sw42'
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'displays an error when the node is not found' do
|
41
|
+
@nodes.expects(:fetch).raises(Oxidized::NodeNotFound, 'unable to find \'sw12\'')
|
42
|
+
|
43
|
+
get '/node/fetch/sw12'
|
44
|
+
_(last_response.ok?).must_equal true
|
45
|
+
_(last_response.body).must_equal 'unable to find \'sw12\''
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '/node/next/' do
|
50
|
+
it 'marks a node to be reloaded, then redirects to /nodes' do
|
51
|
+
# Don't know why the method has been called Nodes#next...
|
52
|
+
# This is for reloading the node configuration
|
53
|
+
@nodes.expects(:next).with('sw42')
|
54
|
+
get '/node/next/sw42'
|
55
|
+
|
56
|
+
_(last_response.redirect?).must_equal true
|
57
|
+
_(last_response.location).must_equal 'http://example.org/nodes'
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'returns ok when requiring json' do
|
61
|
+
@nodes.expects(:next).with('sw42')
|
62
|
+
get '/node/next/sw42.json'
|
63
|
+
|
64
|
+
_(last_response.ok?).must_equal true
|
65
|
+
_(last_response.body).must_equal '["ok"]'
|
66
|
+
end
|
67
|
+
|
68
|
+
# Don't know if this feature is used by anyone...
|
69
|
+
it 'attaches user/email/message to the commit when using put and json' do
|
70
|
+
data = {
|
71
|
+
'user' => 'me',
|
72
|
+
'email' => 'me@example.com',
|
73
|
+
'message' => 'minitest, rack/test & mock simply rock',
|
74
|
+
'from' => 'unused variable!'
|
75
|
+
}
|
76
|
+
@nodes.expects(:next).with('sw42', data)
|
77
|
+
|
78
|
+
put '/node/next/sw42.json', data.to_json, "CONTENT_TYPE" => "application/json"
|
79
|
+
|
80
|
+
_(last_response.ok?).must_equal true
|
81
|
+
_(last_response.body).must_equal '["ok"]'
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'attaches data to the commit when using a group and put, then redirects' do
|
85
|
+
data = {
|
86
|
+
'user' => 'me',
|
87
|
+
'email' => 'me@example.com',
|
88
|
+
'message' => 'minitest, rack/test & mock simply rock',
|
89
|
+
'from' => 'unused variable!'
|
90
|
+
}
|
91
|
+
@nodes.expects(:next).with('sw42', data)
|
92
|
+
|
93
|
+
put '/node/next/mygroup/sw42', data.to_json, "CONTENT_TYPE" => "application/json"
|
94
|
+
|
95
|
+
_(last_response.redirect?).must_equal true
|
96
|
+
_(last_response.location).must_equal 'http://example.org/nodes'
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe Oxidized::API::WebApp do
|
4
|
+
include Rack::Test::Methods
|
5
|
+
|
6
|
+
def app
|
7
|
+
Oxidized::API::WebApp
|
8
|
+
end
|
9
|
+
|
10
|
+
before do
|
11
|
+
@nodes = mock('Oxidized::Nodes')
|
12
|
+
app.set(:nodes, @nodes)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '/node/version.?:format?' do
|
16
|
+
it 'fetches all versions of a node without a group' do
|
17
|
+
@nodes.expects(:version).with('sw5', nil).returns(
|
18
|
+
[{ oid: "C006", date: "2025-02-05 19:49:00 +0100" },
|
19
|
+
{ oid: "C003", date: "2025-02-05 19:03:00 +0100" },
|
20
|
+
{ oid: "C001", date: "2025-02-05 19:01:00 +0100" }]
|
21
|
+
)
|
22
|
+
|
23
|
+
get '/node/version?node_full=sw5'
|
24
|
+
_(last_response.ok?).must_equal true
|
25
|
+
_(last_response.body.include?(
|
26
|
+
"<tr>\n<td>3</td>\n<td>2025-02-05 19:49:00 +0100</td>\n"
|
27
|
+
)).must_equal true
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'fetches all versions of a node with a group' do
|
31
|
+
@nodes.expects(:version).with('sw5', 'group1').returns(
|
32
|
+
[{ oid: "C006", date: "2025-02-05 19:49:00 +0100" },
|
33
|
+
{ oid: "C003", date: "2025-02-05 19:03:00 +0100" },
|
34
|
+
{ oid: "C001", date: "2025-02-05 19:01:00 +0100" }]
|
35
|
+
)
|
36
|
+
|
37
|
+
get '/node/version?node_full=group1/sw5'
|
38
|
+
_(last_response.ok?).must_equal true
|
39
|
+
_(last_response.body.include?(
|
40
|
+
"<tr>\n<td>3</td>\n<td>2025-02-05 19:49:00 +0100</td>\n"
|
41
|
+
)).must_equal true
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'fetches all versions of a node with a group with /' do
|
45
|
+
@nodes.expects(:version).with('sw5', 'gr/oup1').returns(
|
46
|
+
[{ oid: "C006", date: "2025-02-05 19:49:00 +0100" },
|
47
|
+
{ oid: "C003", date: "2025-02-05 19:03:00 +0100" },
|
48
|
+
{ oid: "C001", date: "2025-02-05 19:01:00 +0100" }]
|
49
|
+
)
|
50
|
+
|
51
|
+
get '/node/version?node_full=gr/oup1/sw5'
|
52
|
+
_(last_response.ok?).must_equal true
|
53
|
+
_(last_response.body.include?(
|
54
|
+
"<tr>\n<td>3</td>\n<td>2025-02-05 19:49:00 +0100</td>\n"
|
55
|
+
)).must_equal true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '/node/version/view.?:format?' do
|
60
|
+
it 'fetches a previous version from git' do
|
61
|
+
@nodes.expects(:get_version).with('sw5', '', 'c8aa93cab5').returns('Old configuration of sw5')
|
62
|
+
|
63
|
+
get '/node/version/view?node=sw5&group=&oid=c8aa93cab5&date=2024-06-07 08:27:37 +0200&num=2'
|
64
|
+
_(last_response.ok?).must_equal true
|
65
|
+
_(last_response.body.include?('Old configuration of sw5')).must_equal true
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'does not display binary content' do
|
69
|
+
@nodes.expects(:get_version).with('sw5', '', 'c8aa93cab5').returns("\xff\x42 binary content\x00")
|
70
|
+
|
71
|
+
get '/node/version/view?node=sw5&group=&oid=c8aa93cab5&date=2024-06-07 08:27:37 +0200&num=2'
|
72
|
+
_(last_response.ok?).must_equal true
|
73
|
+
_(last_response.body.include?('cannot display')).must_equal true
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'fetches a git-version when using a group containing /' do
|
77
|
+
@nodes.expects(:get_version).with('sw5', 'my/group', 'c8aa93cab5').returns('Old configuration of sw5')
|
78
|
+
|
79
|
+
get '/node/version/view?node=sw5&group=my/group&oid=c8aa93cab5&date=2024-06-07 08:27:37 +0200&num=2'
|
80
|
+
_(last_response.ok?).must_equal true
|
81
|
+
_(last_response.body.include?('Old configuration of sw5')).must_equal true
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'does not encode html-chars in text-format' do
|
85
|
+
configuration = "text &/<> \n ascii;"
|
86
|
+
@nodes.expects(:get_version).with('sw5', '', 'c8aa93cab5').returns(configuration)
|
87
|
+
get '/node/version/view?node=sw5&group=&oid=c8aa93cab5&date=2024-06-07 08:27:37 +0200&num=2&format=text'
|
88
|
+
|
89
|
+
_(last_response.ok?).must_equal true
|
90
|
+
_(last_response.body).must_equal configuration
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'does not encode html-chars in json-format' do
|
94
|
+
configuration = "text &/<> \n ascii;"
|
95
|
+
@nodes.expects(:get_version).with('sw5', '', 'c8aa93cab5').returns(configuration)
|
96
|
+
get '/node/version/view?node=sw5&group=&oid=c8aa93cab5&date=2024-06-07 08:27:37 +0200&num=2&format=json'
|
97
|
+
|
98
|
+
_(last_response.ok?).must_equal true
|
99
|
+
_(last_response.body).must_equal '["text &/<> \n"," ascii;"]'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/spec/nodes_spec.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
describe Oxidized::API::WebApp do
|
5
|
+
include Rack::Test::Methods
|
6
|
+
|
7
|
+
def app
|
8
|
+
Oxidized::API::WebApp
|
9
|
+
end
|
10
|
+
|
11
|
+
before do
|
12
|
+
@nodes = mock('Oxidized::Nodes')
|
13
|
+
@nodes.expects(:list).returns(
|
14
|
+
[{ name: 'sw4', ip: '10.10.10.10', model: 'ios', time: 'time', mtime: 'mtime' },
|
15
|
+
{ name: 'sw5', ip: '10.10.10.5', model: 'ios', time: 'time', mtime: 'mtime' },
|
16
|
+
{ name: 'sw6', ip: '10.10.10.6', model: 'ios', time: 'time', mtime: 'mtime' },
|
17
|
+
{ name: 'sw7', ip: '10.10.10.7', model: 'ios', time: 'time', mtime: 'mtime', group: 'group1' },
|
18
|
+
{ name: 'sw8', ip: '10.10.10.8', model: 'aos', time: 'time', mtime: 'mtime', group: 'group1' },
|
19
|
+
{ name: 'sw9', ip: '10.10.10.9', model: 'aos', time: 'time', mtime: 'mtime', group: 'gr/oup1' }]
|
20
|
+
)
|
21
|
+
app.set(:nodes, @nodes)
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '/nodes.?:format?' do
|
25
|
+
it 'shows all nodes' do
|
26
|
+
get '/nodes.json'
|
27
|
+
|
28
|
+
_(last_response.ok?).must_equal true
|
29
|
+
result = JSON.parse(last_response.body)
|
30
|
+
_(result.length).must_equal 6
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '/nodes/:filter/*' do
|
35
|
+
it 'shows all nodes of a group' do
|
36
|
+
get '/nodes/group/group1.json'
|
37
|
+
|
38
|
+
_(last_response.ok?).must_equal true
|
39
|
+
result = JSON.parse(last_response.body)
|
40
|
+
_(result.length).must_equal 2
|
41
|
+
end
|
42
|
+
it 'shows all nodes of a group with /' do
|
43
|
+
get '/nodes/group/gr/oup1.json'
|
44
|
+
|
45
|
+
_(last_response.ok?).must_equal true
|
46
|
+
result = JSON.parse(last_response.body)
|
47
|
+
_(result.length).must_equal 1
|
48
|
+
end
|
49
|
+
it 'shows all nodes of a model' do
|
50
|
+
get '/nodes/model/ios.json'
|
51
|
+
|
52
|
+
_(last_response.ok?).must_equal true
|
53
|
+
result = JSON.parse(last_response.body)
|
54
|
+
_(result.length).must_equal 4
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/spec/root_spec.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe Oxidized::API::WebApp do
|
4
|
+
include Rack::Test::Methods
|
5
|
+
|
6
|
+
def app
|
7
|
+
Oxidized::API::WebApp
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '/' do
|
11
|
+
it 'should redirect to /nodes' do
|
12
|
+
get '/'
|
13
|
+
|
14
|
+
_(last_response.redirect?).must_equal true
|
15
|
+
_(last_response.location).must_equal 'http://example.org/nodes'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# Needed to get the error output on the console and not in last_response.body
|
2
|
+
ENV['APP_ENV'] = 'test'
|
3
|
+
|
4
|
+
require 'simplecov'
|
5
|
+
SimpleCov.start
|
6
|
+
|
7
|
+
require 'minitest/autorun'
|
8
|
+
require 'rack/test'
|
9
|
+
require 'oxidized'
|
10
|
+
require 'oxidized/web/webapp'
|
11
|
+
require 'mocha/minitest'
|
data/spec/webapp_spec.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
# Test helper methods in Oxidized::API::WebApp
|
4
|
+
|
5
|
+
describe Oxidized::API::WebApp do
|
6
|
+
include Rack::Test::Methods
|
7
|
+
|
8
|
+
before do
|
9
|
+
@webapp = Oxidized::API::WebApp.new
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'convert_to_utf8' do
|
13
|
+
it 'cannot work with binary data' do
|
14
|
+
# private method => we must use send
|
15
|
+
result = @webapp.helpers.send(:convert_to_utf8, "\xff\x42 binary content\x00")
|
16
|
+
_(result).must_equal 'The text contains binary values - cannot display'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'diff_view' do
|
21
|
+
it 'cannot work with binary data' do
|
22
|
+
# private method => we must use send
|
23
|
+
result = @webapp.helpers.send(:diff_view, "\xff\x42 binary content\x00")
|
24
|
+
_(result[:old_diff]).must_equal ['The text contains binary values - cannot display']
|
25
|
+
_(result[:new_diff]).must_equal ['The text contains binary values - cannot display']
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|