puppet-herald 0.2.0 → 0.8.0
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 +5 -13
- data/.gitignore +3 -0
- data/.jshintrc +19 -0
- data/Gemfile +25 -12
- data/Gemfile.local.example +3 -0
- data/Guardfile +57 -0
- data/README.md +1 -1
- data/Rakefile +100 -20
- data/db/migrate/20141218200108_remove_no_of_reports_from_nodes.rb +7 -0
- data/lib/puppet-herald.rb +95 -65
- data/lib/puppet-herald/app/api.rb +79 -12
- data/lib/puppet-herald/app/configuration.rb +47 -15
- data/lib/puppet-herald/app/frontend.rb +6 -6
- data/lib/puppet-herald/app/views/app.erb +14 -20
- data/lib/puppet-herald/app/views/err500.erb +8 -5
- data/lib/puppet-herald/application.rb +9 -1
- data/lib/puppet-herald/cli.rb +5 -11
- data/lib/puppet-herald/database.rb +1 -7
- data/lib/puppet-herald/javascript.rb +16 -10
- data/lib/puppet-herald/models.rb +47 -0
- data/lib/puppet-herald/models/log-entry.rb +2 -0
- data/lib/puppet-herald/models/node.rb +49 -2
- data/lib/puppet-herald/models/report.rb +33 -9
- data/lib/puppet-herald/project.js +46 -0
- data/lib/puppet-herald/public/app.js +11 -9
- data/lib/puppet-herald/public/bower.json +10 -3
- data/lib/puppet-herald/public/components/artifact/artifact-directive.js +4 -0
- data/lib/puppet-herald/public/components/artifact/artifact.js +1 -3
- data/lib/puppet-herald/public/components/directives/directives.js +5 -1
- data/lib/puppet-herald/public/components/directives/status-button.html +1 -1
- data/lib/puppet-herald/public/components/directives/status-button.js +11 -11
- data/lib/puppet-herald/public/components/filters/filters.js +6 -2
- data/lib/puppet-herald/public/components/page.js +2 -2
- data/lib/puppet-herald/public/components/pagination.js +142 -0
- data/lib/puppet-herald/public/components/settings.js +25 -0
- data/lib/puppet-herald/public/css/herald.css +100 -3
- data/lib/puppet-herald/public/general/app.html +73 -0
- data/lib/puppet-herald/public/img/shield97-white.svg +53 -0
- data/lib/puppet-herald/public/img/shield97.png +0 -0
- data/lib/puppet-herald/public/node/node.html +27 -9
- data/lib/puppet-herald/public/node/node.js +43 -15
- data/lib/puppet-herald/public/nodes/nodes.html +25 -7
- data/lib/puppet-herald/public/nodes/nodes.js +29 -14
- data/lib/puppet-herald/public/report/report.html +60 -13
- data/lib/puppet-herald/public/report/report.js +21 -14
- data/lib/puppet-herald/public/router.js +55 -0
- data/lib/puppet-herald/purgecronjob.rb +35 -0
- data/lib/puppet-herald/version.rb +2 -2
- data/package.json +14 -16
- data/puppet-herald.gemspec +12 -7
- data/spec/integration/app/configuration_spec.rb +33 -0
- data/spec/integration/application_spec.rb +139 -20
- data/spec/integration/fixtures/nodes.yml +13 -0
- data/spec/integration/fixtures/pending-notify.yaml +346 -0
- data/spec/integration/fixtures/reports.yml +61 -0
- data/spec/integration/models/node_spec.rb +12 -3
- data/spec/integration/models/report_spec.rb +60 -4
- data/spec/spec_helper.rb +6 -10
- data/spec/support/active_record.rb +1 -0
- data/spec/support/fixtures.rb +16 -0
- data/spec/unit/puppet-herald/cli_spec.rb +4 -4
- data/spec/unit/puppet-herald/database_spec.rb +5 -3
- data/spec/unit/puppet-herald/purgecronjob_spec.rb +37 -0
- data/test/javascript/.bowerrc +3 -0
- data/test/javascript/bower.json +21 -0
- data/test/javascript/karma.conf.js +17 -22
- data/test/javascript/src/app_test.js +10 -61
- data/test/javascript/src/components/directives/status-button_test.js +10 -10
- data/test/javascript/src/components/paginate_test.js +183 -0
- data/test/javascript/src/node/node_test.js +16 -6
- data/test/javascript/src/nodes/nodes_test.js +14 -2
- data/test/javascript/src/report/report_test.js +6 -6
- data/test/javascript/src/router_test.js +79 -0
- metadata +642 -23
@@ -1,6 +1,3 @@
|
|
1
|
-
require 'puppet-herald'
|
2
|
-
require 'uglifier'
|
3
|
-
|
4
1
|
# A module for Herald
|
5
2
|
module PuppetHerald
|
6
3
|
# A javascript processing class
|
@@ -14,11 +11,13 @@ module PuppetHerald
|
|
14
11
|
# Returns a list of JS files to be inserted into main HTML
|
15
12
|
# @return [Array] list of JS's
|
16
13
|
def files
|
14
|
+
require 'puppet-herald'
|
17
15
|
@files = nil if PuppetHerald.in_dev?
|
18
16
|
if @files.nil?
|
19
17
|
public_dir = PuppetHerald.relative_dir(@base)
|
20
18
|
all = Dir.chdir(public_dir) { Dir.glob('**/*.js') }
|
21
|
-
|
19
|
+
all = all.reverse.reject { |file| file.match(/_test\.js$/) }
|
20
|
+
@files = all.reject { |file| file.match(/bower_components/) }
|
22
21
|
end
|
23
22
|
@files
|
24
23
|
end
|
@@ -27,14 +26,21 @@ module PuppetHerald
|
|
27
26
|
# @param mapname [String] name of source map to be put into uglified JS
|
28
27
|
# @return [Hash] a hash with uglified JS and source map
|
29
28
|
def uglify(mapname)
|
30
|
-
|
29
|
+
require 'uglifier'
|
30
|
+
filenames = files
|
31
|
+
sources = filenames.collect { |file| File.read("#{@base}/#{file}") }
|
31
32
|
source = sources.join "\n"
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
options = {
|
34
|
+
source_map_url: mapname,
|
35
|
+
source_filename: filenames[0],
|
36
|
+
compress: {
|
37
|
+
angular: true,
|
38
|
+
hoist_vars: true
|
39
|
+
}
|
37
40
|
}
|
41
|
+
uglifier = Uglifier.new(options)
|
42
|
+
uglified, source_map = uglifier.compile_with_map(source)
|
43
|
+
{ 'js' => uglified, 'js.map' => source_map }
|
38
44
|
end
|
39
45
|
end
|
40
46
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# A module for Herald
|
2
|
+
module PuppetHerald
|
3
|
+
# module for models
|
4
|
+
module Models
|
5
|
+
# Pagianation object
|
6
|
+
class Pagination
|
7
|
+
# Pagination headers
|
8
|
+
KEYS = {
|
9
|
+
page: 'X-Paginate-Page',
|
10
|
+
limit: 'X-Paginate-Limit',
|
11
|
+
total: 'X-Paginate-Elements',
|
12
|
+
pages: 'X-Paginate-Pages'
|
13
|
+
}
|
14
|
+
# Pagination attribute limit
|
15
|
+
# @return [Integer] pagination
|
16
|
+
attr_reader :page, :limit, :pages, :total
|
17
|
+
# Pagination attribute offset
|
18
|
+
# @return [Integer] pagination
|
19
|
+
def offset
|
20
|
+
(page - 1) * limit
|
21
|
+
end
|
22
|
+
# Sets a total elements for pagination
|
23
|
+
# @param total [Integer] a total number of elements
|
24
|
+
# @return [nil]
|
25
|
+
def total=(total)
|
26
|
+
@total = total.to_i
|
27
|
+
@pages = (@total / @limit.to_f).ceil
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
# A constructor
|
31
|
+
#
|
32
|
+
# @param page [Integer] page to fetch
|
33
|
+
# @param limit [Integer] pagination limit
|
34
|
+
def initialize(page, limit)
|
35
|
+
msg = 'Invalid value for pagination'
|
36
|
+
fail ArgumentError, "#{msg} limit - #{limit.inspect}" unless limit.to_i >= 1
|
37
|
+
fail ArgumentError, "#{msg} page #{page.inspect}" if page.to_i < 1
|
38
|
+
@limit = limit.to_i
|
39
|
+
@page = page.to_i
|
40
|
+
@total = nil
|
41
|
+
@pages = nil
|
42
|
+
end
|
43
|
+
# A default pagination settings
|
44
|
+
DEFAULT = PuppetHerald::Models::Pagination.new(1, 20)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -1,3 +1,7 @@
|
|
1
|
+
require 'puppet-herald/models'
|
2
|
+
require 'puppet-herald/models/report'
|
3
|
+
require 'sinatra/activerecord'
|
4
|
+
|
1
5
|
# A module for Herald
|
2
6
|
module PuppetHerald
|
3
7
|
# module for models
|
@@ -6,11 +10,54 @@ module PuppetHerald
|
|
6
10
|
class Node < ActiveRecord::Base
|
7
11
|
has_many :reports, dependent: :delete_all
|
8
12
|
|
13
|
+
# Paginete thru nodes reports
|
14
|
+
#
|
15
|
+
# @param pagination [PuppetHerald::Models::Pagination] a pagination
|
16
|
+
# @return [Node] fetched node
|
17
|
+
def paginate_reports(pagination)
|
18
|
+
pagination.total = no_of_reports
|
19
|
+
paginated = reports.order(time: :desc).limit(pagination.limit)
|
20
|
+
.offset(pagination.offset)
|
21
|
+
duplicate = dup
|
22
|
+
duplicate.reports = paginated
|
23
|
+
duplicate.id = id
|
24
|
+
duplicate.readonly!
|
25
|
+
duplicate
|
26
|
+
end
|
27
|
+
|
28
|
+
# Gets number of reports for node
|
29
|
+
#
|
30
|
+
# @return [Integer] number of node's reports
|
31
|
+
def no_of_reports
|
32
|
+
PuppetHerald::Models::Report.where(node_id: id).count
|
33
|
+
end
|
34
|
+
|
35
|
+
# Deletes nodes that doesn't have reports
|
36
|
+
#
|
37
|
+
# @return [Integer] number of empty node deleted
|
38
|
+
def self.delete_empty
|
39
|
+
joinsql = 'LEFT JOIN "reports" ON "reports"."node_id" = "nodes"."id"'
|
40
|
+
wheresql = '"reports"."node_id" IS NULL'
|
41
|
+
joins(joinsql).where(wheresql).delete_all if joins(joinsql).where(wheresql).count > 0
|
42
|
+
end
|
43
|
+
|
9
44
|
# Gets a node with prefetched reports
|
45
|
+
#
|
10
46
|
# @param id [Integer] a in of node to get
|
47
|
+
# @param pagination [PuppetHerald::Models::Pagination] a pagination
|
11
48
|
# @return [Node, nil] fetched node or nil
|
12
|
-
def self.
|
13
|
-
|
49
|
+
def self.with_reports(id, pagination = PuppetHerald::Models::Pagination::DEFAULT)
|
50
|
+
node = find_by_id(id)
|
51
|
+
node.paginate_reports pagination unless node.nil?
|
52
|
+
end
|
53
|
+
|
54
|
+
# Gets a paginated nodes
|
55
|
+
#
|
56
|
+
# @param pagination [PuppetHerald::Models::Pagination] a pagination
|
57
|
+
# @return [Node[]] nodes
|
58
|
+
def self.paginate(pagination)
|
59
|
+
pagination.total = count
|
60
|
+
order(last_run: :desc).limit(pagination.limit).offset(pagination.offset)
|
14
61
|
end
|
15
62
|
end
|
16
63
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'puppet-herald/models/log-entry'
|
2
2
|
require 'puppet-herald/models/node'
|
3
3
|
require 'puppet-herald/stubs/puppet'
|
4
|
+
require 'sinatra/activerecord'
|
4
5
|
|
5
6
|
# A module for Herald
|
6
7
|
module PuppetHerald
|
@@ -15,7 +16,7 @@ module PuppetHerald
|
|
15
16
|
# Gets a report with prefetched log entries
|
16
17
|
# @param id [Integer] a in of report to get
|
17
18
|
# @return [Report, nil] fetched report or nil
|
18
|
-
def
|
19
|
+
def with_log_entries(id)
|
19
20
|
Report.joins(:log_entries).includes(:log_entries).find_by_id(id)
|
20
21
|
end
|
21
22
|
|
@@ -24,17 +25,38 @@ module PuppetHerald
|
|
24
25
|
# @return [Report] created report
|
25
26
|
def create_from_yaml(yaml)
|
26
27
|
parsed = parse_yaml yaml
|
27
|
-
report =
|
28
|
+
report = nil
|
29
|
+
transaction do
|
30
|
+
report = Report.new
|
28
31
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
+
parse_properties parsed, report
|
33
|
+
parse_logs parsed, report
|
34
|
+
node = parse_node parsed, report
|
32
35
|
|
33
|
-
|
34
|
-
|
36
|
+
report.save
|
37
|
+
node.save
|
38
|
+
end
|
35
39
|
report
|
36
40
|
end
|
37
41
|
|
42
|
+
# Purges older reports then given date
|
43
|
+
#
|
44
|
+
# @param date [DateTime] a date that will be border to
|
45
|
+
# @return [Integer] number of
|
46
|
+
def purge_older_then(date)
|
47
|
+
deleted = 0
|
48
|
+
query = ['"reports"."time" < ?', date]
|
49
|
+
return 0 if where(query).count == 0
|
50
|
+
transaction do
|
51
|
+
idss = joins(:log_entries).where(query).collect(&:id).uniq
|
52
|
+
PuppetHerald::Models::LogEntry.where(['"report_id" IN (?)', idss]).delete_all unless idss.empty?
|
53
|
+
where(['"id" IN (?)', idss]).delete_all unless idss.empty?
|
54
|
+
PuppetHerald::Models::Node.delete_empty
|
55
|
+
deleted = idss.length
|
56
|
+
end
|
57
|
+
deleted
|
58
|
+
end
|
59
|
+
|
38
60
|
private
|
39
61
|
|
40
62
|
def parse_node(parsed, report)
|
@@ -42,11 +64,9 @@ module PuppetHerald
|
|
42
64
|
if node.nil?
|
43
65
|
node = Node.new
|
44
66
|
node.name = parsed.host
|
45
|
-
node.no_of_reports = 0
|
46
67
|
end
|
47
68
|
report.node = node
|
48
69
|
node.reports << report
|
49
|
-
node.no_of_reports += 1
|
50
70
|
node.status = parsed.status
|
51
71
|
node.last_run = parsed.time
|
52
72
|
node
|
@@ -62,6 +82,10 @@ module PuppetHerald
|
|
62
82
|
log = LogEntry.new
|
63
83
|
attr_to_copy = %w(level message source time)
|
64
84
|
copy_attrs in_log, log, attr_to_copy
|
85
|
+
if log.message.include?('(noop)') && report.status != 'failed'
|
86
|
+
report.status = 'pending'
|
87
|
+
parsed.status = 'pending'
|
88
|
+
end
|
65
89
|
log.report = report
|
66
90
|
report.log_entries << log
|
67
91
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
var fs = require('fs');
|
4
|
+
var wiredep = require('wiredep');
|
5
|
+
var globby = require('globby');
|
6
|
+
|
7
|
+
var cwd = '../..';
|
8
|
+
var root = fs.realpathSync(__dirname + '/' + cwd);
|
9
|
+
var publicDir = 'lib/puppet-herald/public';
|
10
|
+
var dependencies = wiredep({
|
11
|
+
cwd: publicDir,
|
12
|
+
dependencies: true,
|
13
|
+
devDependencies: false
|
14
|
+
}).js.map(function(file) {
|
15
|
+
return file.replace(root + '/', '');
|
16
|
+
});
|
17
|
+
var devDependencies = wiredep({
|
18
|
+
cwd: 'test/javascript',
|
19
|
+
dependencies: false,
|
20
|
+
devDependencies: true,
|
21
|
+
exclude: 'angular/angular.js'
|
22
|
+
}).js.map(function(file) {
|
23
|
+
return file.replace(root + '/', '');
|
24
|
+
});
|
25
|
+
var files = {
|
26
|
+
html: globby.sync([publicDir+'/**/*.html', '!**/bower_components/**']),
|
27
|
+
js: globby.sync([publicDir+'/**/*.js', '!**/bower_components/**']),
|
28
|
+
tests: globby.sync(['test/javascript/src/**/*_test.js'])
|
29
|
+
};
|
30
|
+
var search = {
|
31
|
+
coverage: publicDir + '/!(*bower_components)/**/*.js',
|
32
|
+
html2js: publicDir + '/!(*bower_components)/**/*.html'
|
33
|
+
};
|
34
|
+
var preprocessors = {};
|
35
|
+
preprocessors[search.coverage] = ['coverage'];
|
36
|
+
preprocessors[search.html2js] = ['ng-html2js'];
|
37
|
+
|
38
|
+
module.exports = {
|
39
|
+
cwd: cwd,
|
40
|
+
root: root,
|
41
|
+
publicDir: publicDir,
|
42
|
+
dependencies: dependencies,
|
43
|
+
devDependencies: devDependencies,
|
44
|
+
preprocessors: preprocessors,
|
45
|
+
files: files
|
46
|
+
};
|
@@ -2,8 +2,10 @@
|
|
2
2
|
'use strict';
|
3
3
|
|
4
4
|
var app = angular.module('herald' , [
|
5
|
-
'
|
5
|
+
'ui.router',
|
6
|
+
'herald.router',
|
6
7
|
'herald.page',
|
8
|
+
'herald.settings',
|
7
9
|
'herald.nodes',
|
8
10
|
'herald.node',
|
9
11
|
'herald.report',
|
@@ -11,17 +13,17 @@
|
|
11
13
|
'herald.artifact'
|
12
14
|
]);
|
13
15
|
|
14
|
-
app.
|
15
|
-
$
|
16
|
-
|
16
|
+
app.controller('AppController',
|
17
|
+
['Page', '$rootScope', 'Settings', '$scope',
|
18
|
+
function(Page, $rootScope, Settings, $scope) {
|
17
19
|
|
18
|
-
app.controller('AppController', ['Page', '$rootScope', function(Page, $rootScope) {
|
19
20
|
var ctrl = this;
|
20
|
-
|
21
|
-
|
21
|
+
$scope.page = null;
|
22
|
+
$scope.target = null;
|
23
|
+
$scope.settings = Settings;
|
22
24
|
$rootScope.$on('Page::titleChanged', function(event, title, target) {
|
23
|
-
|
24
|
-
|
25
|
+
$scope.page = title;
|
26
|
+
$scope.target = target;
|
25
27
|
});
|
26
28
|
}]);
|
27
29
|
|
@@ -1,13 +1,20 @@
|
|
1
1
|
{
|
2
2
|
"name": "puppet-herald",
|
3
3
|
"description": "Report processor for Puppet",
|
4
|
-
"version": "0.
|
4
|
+
"version": "0.2.0",
|
5
5
|
"homepage": "https://github.com/wavesoftware/gem-puppet-herald",
|
6
|
-
"license": "Apache
|
6
|
+
"license": "Apache-2.0",
|
7
7
|
"private": false,
|
8
8
|
"dependencies": {
|
9
9
|
"angular": "1.3.x",
|
10
|
-
"angular-
|
10
|
+
"angular-moment": "0.10.x",
|
11
|
+
"angular-ui-router": "0.2.x",
|
12
|
+
"bootstrap": "3.3.x",
|
13
|
+
"angular-utils-pagination": "0.6.x",
|
14
|
+
"angular-breadcrumb": "0.3.x",
|
15
|
+
"ngstorage": "0.3.x"
|
16
|
+
},
|
17
|
+
"devDependencies": {
|
11
18
|
"angular-loader": "1.3.x",
|
12
19
|
"angular-mocks": "1.3.x"
|
13
20
|
}
|
@@ -2,27 +2,27 @@
|
|
2
2
|
|
3
3
|
'use strict';
|
4
4
|
|
5
|
-
var module = angular.module('herald.directives.status-button', [
|
5
|
+
var module = angular.module('herald.directives.status-button', [ 'ui.router' ]);
|
6
6
|
|
7
|
-
|
7
|
+
module.controller('StatusButtonController', ['$state', '$scope', function($state, $scope) {
|
8
8
|
|
9
|
-
|
9
|
+
$scope.$state = $state;
|
10
10
|
|
11
|
-
$scope
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
this.$location.path(target);
|
11
|
+
$scope.navigate = function(route, idName, id) {
|
12
|
+
var params = {};
|
13
|
+
params[idName] = id;
|
14
|
+
this.$state.go(route, params);
|
16
15
|
};
|
17
16
|
|
18
17
|
}]);
|
19
18
|
|
20
|
-
module.directive('
|
19
|
+
module.directive('wsStatusButton', function() {
|
21
20
|
return {
|
22
21
|
restrict: 'E',
|
23
22
|
scope: {
|
24
23
|
status: '=',
|
25
24
|
id: '=',
|
25
|
+
idname: '=',
|
26
26
|
route: '='
|
27
27
|
},
|
28
28
|
controller: 'StatusButtonController',
|
@@ -39,7 +39,7 @@
|
|
39
39
|
case 'pending': return 'warning';
|
40
40
|
default: return 'default';
|
41
41
|
}
|
42
|
-
}
|
42
|
+
};
|
43
43
|
});
|
44
44
|
|
45
45
|
module.filter('iconizeStatus', function() {
|
@@ -51,6 +51,6 @@
|
|
51
51
|
case 'pending': return 'asterisk';
|
52
52
|
default: return 'sign';
|
53
53
|
}
|
54
|
-
}
|
54
|
+
};
|
55
55
|
});
|
56
56
|
})();
|