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.

Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.github/PULL_REQUEST_TEMPLATE.md +12 -0
  3. data/.github/dependabot.yml +25 -0
  4. data/.github/workflows/codeql.yml +76 -0
  5. data/.github/workflows/ruby.yml +41 -0
  6. data/.github/workflows/stale.yml +20 -0
  7. data/.gitignore +3 -0
  8. data/.rubocop.yml +38 -3
  9. data/.rubocop_todo.yml +27 -211
  10. data/CHANGELOG.md +46 -0
  11. data/README.md +8 -5
  12. data/Rakefile +49 -5
  13. data/docs/development.md +182 -0
  14. data/lib/oxidized/web/public/css/oxidized.css +59 -0
  15. data/lib/oxidized/web/public/scripts/oxidized.js +1 -48
  16. data/lib/oxidized/web/public/weblibs/bootstrap-icons.css +2078 -0
  17. data/lib/oxidized/web/public/weblibs/bootstrap.bundle.js +6314 -0
  18. data/lib/oxidized/web/public/weblibs/bootstrap.bundle.js.map +1 -0
  19. data/lib/oxidized/web/public/weblibs/bootstrap.css +12057 -0
  20. data/lib/oxidized/web/public/weblibs/bootstrap.css.map +1 -0
  21. data/lib/oxidized/web/public/weblibs/bootstrap.js +4494 -0
  22. data/lib/oxidized/web/public/weblibs/bootstrap.js.map +1 -0
  23. data/lib/oxidized/web/public/weblibs/buttons.bootstrap5.css +395 -0
  24. data/lib/oxidized/web/public/weblibs/buttons.bootstrap5.js +114 -0
  25. data/lib/oxidized/web/public/weblibs/buttons.colVis.js +256 -0
  26. data/lib/oxidized/web/public/weblibs/dataTables.bootstrap5.css +517 -0
  27. data/lib/oxidized/web/public/weblibs/dataTables.bootstrap5.js +122 -0
  28. data/lib/oxidized/web/public/weblibs/dataTables.buttons.js +2936 -0
  29. data/lib/oxidized/web/public/weblibs/dataTables.js +13843 -0
  30. data/lib/oxidized/web/public/weblibs/fonts/bootstrap-icons.woff +0 -0
  31. data/lib/oxidized/web/public/weblibs/fonts/bootstrap-icons.woff2 +0 -0
  32. data/lib/oxidized/web/public/weblibs/jquery.js +10716 -0
  33. data/lib/oxidized/web/version.rb +7 -0
  34. data/lib/oxidized/web/views/conf_search.haml +14 -13
  35. data/lib/oxidized/web/views/diffs.haml +5 -5
  36. data/lib/oxidized/web/views/footer.haml +5 -4
  37. data/lib/oxidized/web/views/head.haml +21 -7
  38. data/lib/oxidized/web/views/layout.haml +25 -34
  39. data/lib/oxidized/web/views/node.haml +10 -8
  40. data/lib/oxidized/web/views/nodes.haml +45 -35
  41. data/lib/oxidized/web/views/stats.haml +32 -24
  42. data/lib/oxidized/web/views/version.haml +8 -6
  43. data/lib/oxidized/web/views/versions.haml +23 -24
  44. data/lib/oxidized/web/webapp.rb +117 -113
  45. data/lib/oxidized/web.rb +10 -7
  46. data/oxidized-web.gemspec +32 -18
  47. data/package-lock.json +104 -0
  48. data/package.json +21 -0
  49. data/spec/node_spec.rb +99 -0
  50. data/spec/node_version_spec.rb +102 -0
  51. data/spec/nodes_spec.rb +57 -0
  52. data/spec/root_spec.rb +18 -0
  53. data/spec/spec_helper.rb +11 -0
  54. data/spec/webapp_spec.rb +28 -0
  55. metadata +183 -74
  56. data/lib/oxidized/web/mig.rb +0 -150
  57. data/lib/oxidized/web/public/css/bootstrap.min.css +0 -5
  58. data/lib/oxidized/web/public/css/buttons.bootstrap.min.css +0 -1
  59. data/lib/oxidized/web/public/css/dataTables.bootstrap.css +0 -299
  60. data/lib/oxidized/web/public/css/dataTables.colVis.css +0 -171
  61. data/lib/oxidized/web/public/css/oxidized_custom.css +0 -19
  62. data/lib/oxidized/web/public/fonts/glyphicons-halflings-regular.eot +0 -0
  63. data/lib/oxidized/web/public/fonts/glyphicons-halflings-regular.svg +0 -229
  64. data/lib/oxidized/web/public/fonts/glyphicons-halflings-regular.ttf +0 -0
  65. data/lib/oxidized/web/public/fonts/glyphicons-halflings-regular.woff +0 -0
  66. data/lib/oxidized/web/public/images/diff_15x17.png +0 -0
  67. data/lib/oxidized/web/public/images/sort_asc.png +0 -0
  68. data/lib/oxidized/web/public/images/sort_asc_disabled.png +0 -0
  69. data/lib/oxidized/web/public/images/sort_both.png +0 -0
  70. data/lib/oxidized/web/public/images/sort_desc.png +0 -0
  71. data/lib/oxidized/web/public/images/sort_desc_disabled.png +0 -0
  72. data/lib/oxidized/web/public/images/versioning_18px.png +0 -0
  73. data/lib/oxidized/web/public/scripts/bootstrap.min.js +0 -6
  74. data/lib/oxidized/web/public/scripts/dataTables.bootstrap.js +0 -186
  75. data/lib/oxidized/web/public/scripts/dataTables.colVis.js +0 -1123
  76. data/lib/oxidized/web/public/scripts/jquery-2.1.1.min.js +0 -4
  77. data/lib/oxidized/web/public/scripts/jquery.dataTables.min.js +0 -157
  78. data/lib/oxidized/web/public/scripts/jquery.min.js +0 -6
  79. data/lib/oxidized/web/public/scripts/script-migration.js +0 -15
  80. data/lib/oxidized/web/views/migration.haml +0 -46
  81. 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
@@ -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
@@ -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'
@@ -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