puppet-herald 0.1.1 → 0.2.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 +15 -7
- data/.rubocop.yml +31 -0
- data/.rubocop_todo.yml +6 -0
- data/.travis.yml +7 -7
- data/Gemfile +5 -9
- data/README.md +152 -16
- data/Rakefile +67 -6
- data/bin/puppet-herald +1 -1
- data/config.ru +2 -2
- data/db/migrate/20141211165540_create_nodes.rb +5 -3
- data/db/migrate/20141211171305_create_reports.rb +12 -10
- data/db/migrate/20141211171326_create_log_entries.rb +9 -7
- data/db/schema.rb +24 -26
- data/lib/puppet-herald.rb +59 -21
- data/lib/puppet-herald/app/api.rb +111 -0
- data/lib/puppet-herald/app/configuration.rb +70 -0
- data/lib/puppet-herald/app/frontend.rb +61 -0
- data/lib/puppet-herald/{views → app/views}/app.erb +5 -8
- data/lib/puppet-herald/{views → app/views}/err500.erb +1 -4
- data/lib/puppet-herald/application.rb +27 -0
- data/lib/puppet-herald/cli.rb +66 -45
- data/lib/puppet-herald/client.rb +33 -0
- data/lib/puppet-herald/database.rb +84 -40
- data/lib/puppet-herald/javascript.rb +23 -17
- data/lib/puppet-herald/models/log-entry.rb +10 -3
- data/lib/puppet-herald/models/node.rb +15 -5
- data/lib/puppet-herald/models/report.rb +70 -63
- data/lib/puppet-herald/public/app.js +9 -8
- data/lib/puppet-herald/public/components/directives/status-button.html +1 -1
- data/lib/puppet-herald/public/components/directives/status-button.js +5 -3
- data/lib/puppet-herald/public/components/filters/filters.js +9 -4
- data/lib/puppet-herald/public/components/page.js +34 -0
- data/lib/puppet-herald/public/node/node.html +3 -1
- data/lib/puppet-herald/public/node/node.js +7 -4
- data/lib/puppet-herald/public/nodes/nodes.js +3 -2
- data/lib/puppet-herald/public/report/report.html +4 -1
- data/lib/puppet-herald/public/report/report.js +5 -3
- data/lib/puppet-herald/stubs/puppet.rb +20 -9
- data/lib/puppet-herald/version.rb +17 -7
- data/package.json +8 -3
- data/puppet-herald.gemspec +3 -6
- data/spec/integration/application_spec.rb +175 -0
- data/spec/integration/models/node_spec.rb +4 -4
- data/spec/integration/models/report_spec.rb +7 -7
- data/spec/spec_helper.rb +12 -7
- data/spec/support/active_record.rb +6 -10
- data/spec/support/reconnectdb.rb +13 -0
- data/spec/unit/puppet-herald/cli_spec.rb +45 -13
- data/spec/unit/puppet-herald/client_spec.rb +23 -0
- data/spec/unit/puppet-herald/database_spec.rb +8 -9
- data/spec/unit/puppet-herald/javascript_spec.rb +8 -13
- data/spec/unit/puppet-herald_spec.rb +4 -4
- data/test/javascript/karma.conf.js +43 -5
- data/test/javascript/src/app_test.js +90 -0
- data/test/javascript/src/components/artifact/artifact-directive_test.js +36 -0
- data/test/javascript/src/components/artifact/artifact_test.js +64 -0
- data/test/javascript/src/components/directives/status-button_test.js +159 -0
- data/test/javascript/src/components/filters/filters_test.js +35 -0
- data/test/javascript/src/node/node_test.js +87 -0
- data/test/javascript/src/nodes/nodes_test.js +56 -0
- data/test/javascript/src/report/report_test.js +94 -0
- metadata +98 -68
- data/lib/puppet-herald/app.rb +0 -103
- data/lib/puppet-herald/public/components/artifact/artifact-directive_test.js +0 -17
- data/spec/integration/app_spec.rb +0 -21
@@ -2,77 +2,84 @@ require 'puppet-herald/models/log-entry'
|
|
2
2
|
require 'puppet-herald/models/node'
|
3
3
|
require 'puppet-herald/stubs/puppet'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
# A module for Herald
|
6
|
+
module PuppetHerald
|
7
|
+
# module for models
|
8
|
+
module Models
|
9
|
+
# A model for Report
|
10
|
+
class Report < ActiveRecord::Base
|
11
|
+
belongs_to :node
|
12
|
+
has_many :log_entries, dependent: :delete_all
|
8
13
|
|
9
|
-
|
10
|
-
|
11
|
-
|
14
|
+
class << self
|
15
|
+
# Gets a report with prefetched log entries
|
16
|
+
# @param id [Integer] a in of report to get
|
17
|
+
# @return [Report, nil] fetched report or nil
|
18
|
+
def get_with_log_entries(id)
|
19
|
+
Report.joins(:log_entries).includes(:log_entries).find_by_id(id)
|
20
|
+
end
|
12
21
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
node = parse_node parsed, report
|
22
|
+
# Creates a report from given YAML report file
|
23
|
+
# @param yaml [String] a puppet report YAML as string
|
24
|
+
# @return [Report] created report
|
25
|
+
def create_from_yaml(yaml)
|
26
|
+
parsed = parse_yaml yaml
|
27
|
+
report = Report.new
|
20
28
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
29
|
+
parse_properties parsed, report
|
30
|
+
parse_logs parsed, report
|
31
|
+
node = parse_node parsed, report
|
25
32
|
|
26
|
-
|
33
|
+
report.save
|
34
|
+
node.save
|
35
|
+
report
|
36
|
+
end
|
27
37
|
|
28
|
-
|
29
|
-
node = Node.find_by_name(parsed.host)
|
30
|
-
if node.nil?
|
31
|
-
node = Node.new
|
32
|
-
node.name = parsed.host
|
33
|
-
node.no_of_reports = 0
|
34
|
-
end
|
35
|
-
report.node = node
|
36
|
-
node.reports << report
|
37
|
-
node.no_of_reports += 1
|
38
|
-
node.status = parsed.status
|
39
|
-
node.last_run = parsed.time
|
40
|
-
return node
|
41
|
-
end
|
38
|
+
private
|
42
39
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
40
|
+
def parse_node(parsed, report)
|
41
|
+
node = Node.find_by_name(parsed.host)
|
42
|
+
if node.nil?
|
43
|
+
node = Node.new
|
44
|
+
node.name = parsed.host
|
45
|
+
node.no_of_reports = 0
|
46
|
+
end
|
47
|
+
report.node = node
|
48
|
+
node.reports << report
|
49
|
+
node.no_of_reports += 1
|
50
|
+
node.status = parsed.status
|
51
|
+
node.last_run = parsed.time
|
52
|
+
node
|
53
|
+
end
|
52
54
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
'level', 'message',
|
58
|
-
'source', 'time'
|
59
|
-
]
|
60
|
-
copy_attrs in_log, log, attr_to_copy
|
61
|
-
log.report = report
|
62
|
-
report.log_entries << log
|
63
|
-
end
|
64
|
-
end
|
55
|
+
def parse_properties(parsed, report)
|
56
|
+
attr_to_copy = %w(status environment transaction_uuid time puppet_version kind host configuration_version)
|
57
|
+
copy_attrs parsed, report, attr_to_copy
|
58
|
+
end
|
65
59
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
60
|
+
def parse_logs(parsed, report)
|
61
|
+
parsed.logs.each do |in_log|
|
62
|
+
log = LogEntry.new
|
63
|
+
attr_to_copy = %w(level message source time)
|
64
|
+
copy_attrs in_log, log, attr_to_copy
|
65
|
+
log.report = report
|
66
|
+
report.log_entries << log
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def parse_yaml(yaml)
|
71
|
+
require 'yaml'
|
72
|
+
raw = YAML.parse yaml
|
73
|
+
raw.to_ruby
|
74
|
+
end
|
71
75
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
+
def copy_attrs(from, to, attrs)
|
77
|
+
attrs.each do |at|
|
78
|
+
value = from.send at
|
79
|
+
to.send "#{at}=", value
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
76
83
|
end
|
77
84
|
end
|
78
|
-
end
|
85
|
+
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
var app = angular.module('herald' , [
|
5
5
|
'ngRoute',
|
6
|
+
'herald.page',
|
6
7
|
'herald.nodes',
|
7
8
|
'herald.node',
|
8
9
|
'herald.report',
|
@@ -14,14 +15,14 @@
|
|
14
15
|
$routeProvider.otherwise({redirectTo: '/nodes'});
|
15
16
|
}]);
|
16
17
|
|
17
|
-
app.
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
app.controller('AppController', ['Page', '$rootScope', function(Page, $rootScope) {
|
19
|
+
var ctrl = this;
|
20
|
+
this.page = null;
|
21
|
+
this.target = null;
|
22
|
+
$rootScope.$on('Page::titleChanged', function(event, title, target) {
|
23
|
+
ctrl.page = title;
|
24
|
+
ctrl.target = target;
|
25
|
+
});
|
25
26
|
}]);
|
26
27
|
|
27
28
|
})();
|
@@ -10,8 +10,8 @@
|
|
10
10
|
|
11
11
|
$scope.$location = $location;
|
12
12
|
|
13
|
-
$scope.navigate = function() {
|
14
|
-
var target =
|
13
|
+
$scope.navigate = function(route, id) {
|
14
|
+
var target = route.replace(':id', id);
|
15
15
|
this.$location.path(target);
|
16
16
|
};
|
17
17
|
|
@@ -36,6 +36,7 @@
|
|
36
36
|
case 'unchanged': return 'success';
|
37
37
|
case 'changed': return 'info';
|
38
38
|
case 'failed': return 'danger';
|
39
|
+
case 'pending': return 'warning';
|
39
40
|
default: return 'default';
|
40
41
|
}
|
41
42
|
}
|
@@ -47,7 +48,8 @@
|
|
47
48
|
case 'unchanged': return 'ok';
|
48
49
|
case 'changed': return 'pencil';
|
49
50
|
case 'failed': return 'remove';
|
50
|
-
|
51
|
+
case 'pending': return 'asterisk';
|
52
|
+
default: return 'sign';
|
51
53
|
}
|
52
54
|
}
|
53
55
|
});
|
@@ -1,12 +1,17 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
|
-
angular.module('herald.filters', [
|
4
|
-
])
|
3
|
+
angular.module('herald.filters', [])
|
5
4
|
|
6
5
|
.filter('capitalize', function() {
|
7
6
|
return function(input) {
|
8
|
-
var
|
9
|
-
|
7
|
+
var text;
|
8
|
+
if (input == null) {
|
9
|
+
text = '';
|
10
|
+
} else {
|
11
|
+
text = input.toString();
|
12
|
+
}
|
13
|
+
var first = text.substring(0, 1);
|
14
|
+
var rest = text.substring(1);
|
10
15
|
return first.toUpperCase() + rest;
|
11
16
|
};
|
12
17
|
});
|
@@ -0,0 +1,34 @@
|
|
1
|
+
(function(angular){
|
2
|
+
'use strict';
|
3
|
+
|
4
|
+
var module = angular.module('herald.page' , []);
|
5
|
+
|
6
|
+
module.factory('Page', ['$document', '$rootScope', function($document, $rootScope) {
|
7
|
+
var root = $document;
|
8
|
+
var base = root[0].title
|
9
|
+
var title = null;
|
10
|
+
var target = null;
|
11
|
+
var service = {
|
12
|
+
title: function(newTitle, newTarget, joiner) {
|
13
|
+
var merged = newTitle + '';
|
14
|
+
if(typeof(joiner) === 'undefined') joiner = ': ';
|
15
|
+
if (typeof(newTarget) !== 'undefined') {
|
16
|
+
merged = merged + joiner + newTarget;
|
17
|
+
}
|
18
|
+
var whole = merged + ' | ' + base;
|
19
|
+
root[0].title = whole;
|
20
|
+
title = newTitle;
|
21
|
+
target = newTarget;
|
22
|
+
$rootScope.$emit('Page::titleChanged', title, target, merged, whole);
|
23
|
+
},
|
24
|
+
actualTitle: function() {
|
25
|
+
return title;
|
26
|
+
},
|
27
|
+
actualTarget: function() {
|
28
|
+
return target;
|
29
|
+
}
|
30
|
+
};
|
31
|
+
return service;
|
32
|
+
}]);
|
33
|
+
|
34
|
+
})(angular);
|
@@ -1,6 +1,8 @@
|
|
1
1
|
<div class="panel panel-primary" ng-controller="NodeController as ctrl">
|
2
2
|
<!-- Default panel contents -->
|
3
|
-
<div class="panel-heading">Reports for
|
3
|
+
<div class="panel-heading">Reports for
|
4
|
+
<samp>{{ ctrl.node.name }}</samp> <span class="badge">{{ ctrl.node.reports.length }}</span>
|
5
|
+
</div>
|
4
6
|
|
5
7
|
<!-- Table -->
|
6
8
|
<table class="table table-striped table-hover">
|
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
angular.module('herald.node', [
|
4
4
|
'ngRoute',
|
5
|
-
'herald.
|
5
|
+
'herald.page',
|
6
|
+
'herald.directives',
|
7
|
+
'angularMoment'
|
6
8
|
])
|
7
9
|
|
8
10
|
.config(['$routeProvider', function($routeProvider) {
|
@@ -12,13 +14,14 @@ angular.module('herald.node', [
|
|
12
14
|
});
|
13
15
|
}])
|
14
16
|
|
15
|
-
.controller('NodeController', ['$http', '$routeParams', function($http, $routeParams) {
|
17
|
+
.controller('NodeController', ['$http', '$routeParams', 'Page', function($http, $routeParams, Page) {
|
16
18
|
var ctrl = this;
|
17
19
|
ctrl.node = null;
|
18
|
-
|
20
|
+
Page.title('Node');
|
19
21
|
this.nodeId = $routeParams.nodeId;
|
20
22
|
|
21
|
-
$http.get('/api/v1/
|
23
|
+
$http.get('/api/v1/nodes/' + this.nodeId).success(function(data) {
|
22
24
|
ctrl.node = data;
|
25
|
+
Page.title('Node', data.name);
|
23
26
|
});
|
24
27
|
}]);
|
@@ -3,6 +3,7 @@
|
|
3
3
|
angular.module('herald.nodes', [
|
4
4
|
'ngRoute',
|
5
5
|
'herald.directives',
|
6
|
+
'herald.page',
|
6
7
|
'angularMoment'
|
7
8
|
])
|
8
9
|
|
@@ -13,8 +14,8 @@ angular.module('herald.nodes', [
|
|
13
14
|
});
|
14
15
|
}])
|
15
16
|
|
16
|
-
.controller('NodesController', ['$http', '
|
17
|
-
|
17
|
+
.controller('NodesController', ['$http', 'Page', function($http, Page) {
|
18
|
+
Page.title('All nodes');
|
18
19
|
var ctrl = this;
|
19
20
|
ctrl.all = [];
|
20
21
|
|
@@ -1,6 +1,9 @@
|
|
1
1
|
<div class="panel panel-primary" ng-controller="ReportController as ctrl">
|
2
2
|
<!-- Default panel contents -->
|
3
|
-
<div class="panel-heading">Report
|
3
|
+
<div class="panel-heading">Report:
|
4
|
+
<samp>{{ ctrl.report.configuration_version }}</samp>
|
5
|
+
<span class="badge">{{ ctrl.report.log_entries.length }}</span>
|
6
|
+
</div>
|
4
7
|
|
5
8
|
<!-- Table -->
|
6
9
|
<table class="table table-condensed table-hover herald-table-report">
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
angular.module('herald.report', [
|
4
4
|
'ngRoute',
|
5
|
+
'herald.page',
|
5
6
|
'herald.directives'
|
6
7
|
])
|
7
8
|
|
@@ -12,13 +13,14 @@ angular.module('herald.report', [
|
|
12
13
|
});
|
13
14
|
}])
|
14
15
|
|
15
|
-
.controller('ReportController', ['$http', '$routeParams', function($http, $routeParams) {
|
16
|
+
.controller('ReportController', ['$http', '$routeParams', 'Page', function($http, $routeParams, Page) {
|
17
|
+
Page.title('Report');
|
16
18
|
var ctrl = this;
|
17
19
|
ctrl.report = null;
|
18
|
-
|
19
20
|
this.reportId = $routeParams.reportId;
|
20
21
|
|
21
|
-
$http.get('/api/v1/
|
22
|
+
$http.get('/api/v1/reports/' + this.reportId).success(function(data) {
|
22
23
|
ctrl.report = data;
|
24
|
+
Page.title('Report', data.configuration_version);
|
23
25
|
});
|
24
26
|
}]);
|
@@ -1,29 +1,40 @@
|
|
1
|
+
# A stub Puppet module
|
1
2
|
module Puppet
|
3
|
+
# A stub Puppet module
|
2
4
|
module Transaction
|
3
|
-
|
5
|
+
# A stub Puppet class
|
4
6
|
class Report
|
5
|
-
|
7
|
+
# A puppet variable from report
|
8
|
+
# @return [String] a puppet set variable
|
9
|
+
attr_accessor :host, :time, :kind, :puppet_version, :configuration_version
|
10
|
+
|
11
|
+
# A puppet variable from report
|
12
|
+
# @return [String] a puppet set variable
|
13
|
+
attr_accessor :transaction_uuid, :environment, :status, :logs
|
6
14
|
end
|
7
15
|
|
16
|
+
# A stub Puppet class
|
8
17
|
class Event
|
9
|
-
|
10
18
|
end
|
11
|
-
|
12
19
|
end
|
20
|
+
|
21
|
+
# A stub Puppet class
|
13
22
|
class Resource
|
23
|
+
# A stub Puppet class
|
14
24
|
class Status
|
15
|
-
|
16
25
|
end
|
17
26
|
end
|
27
|
+
# A stub Puppet module
|
18
28
|
module Util
|
19
|
-
|
29
|
+
# A stub Puppet class
|
20
30
|
class Log
|
31
|
+
# A puppet variable from report
|
32
|
+
# @return [String] a puppet set variable
|
21
33
|
attr_accessor :level, :message, :source, :time, :line, :tags
|
22
34
|
end
|
23
35
|
|
36
|
+
# A stub Puppet class
|
24
37
|
class Metric
|
25
|
-
|
26
38
|
end
|
27
|
-
|
28
39
|
end
|
29
|
-
end
|
40
|
+
end
|
@@ -1,20 +1,30 @@
|
|
1
|
+
# A module for Herald
|
1
2
|
module PuppetHerald
|
2
|
-
|
3
|
-
|
3
|
+
# Prepare version
|
4
|
+
#
|
5
|
+
# @param desired [String] a desired version
|
6
|
+
# @return [String] a prepared version
|
7
|
+
def self.version_prep(desired)
|
4
8
|
version = desired
|
5
9
|
if desired.match(/[^0-9\.]+/)
|
6
10
|
git = `git describe --tags --dirty --always`
|
7
|
-
version +=
|
11
|
+
version += '.' + git.gsub('-', '.')
|
8
12
|
end
|
9
|
-
|
13
|
+
version.strip
|
10
14
|
end
|
11
15
|
|
12
|
-
|
16
|
+
# Version for Herald
|
17
|
+
VERSION = version_prep '0.2.0'
|
18
|
+
# Lincense for Herald
|
13
19
|
LICENSE = 'Apache 2.0'
|
20
|
+
# Project name
|
14
21
|
NAME = 'Puppet Herald'
|
22
|
+
# Package (gem) for Herald
|
15
23
|
PACKAGE = 'puppet-herald'
|
24
|
+
# A summary info
|
16
25
|
SUMMARY = 'a Puppet report processor'
|
17
|
-
|
26
|
+
# A description info
|
27
|
+
DESCRIPTION = 'Provides a gateway for consuming puppet reports, a REST API and a simple Web app to display reports.'
|
28
|
+
# A homepage for Herald
|
18
29
|
HOMEPAGE = 'https://github.com/wavesoftware/gem-puppet-herald'
|
19
|
-
|
20
30
|
end
|