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.
Files changed (65) hide show
  1. checksums.yaml +15 -7
  2. data/.rubocop.yml +31 -0
  3. data/.rubocop_todo.yml +6 -0
  4. data/.travis.yml +7 -7
  5. data/Gemfile +5 -9
  6. data/README.md +152 -16
  7. data/Rakefile +67 -6
  8. data/bin/puppet-herald +1 -1
  9. data/config.ru +2 -2
  10. data/db/migrate/20141211165540_create_nodes.rb +5 -3
  11. data/db/migrate/20141211171305_create_reports.rb +12 -10
  12. data/db/migrate/20141211171326_create_log_entries.rb +9 -7
  13. data/db/schema.rb +24 -26
  14. data/lib/puppet-herald.rb +59 -21
  15. data/lib/puppet-herald/app/api.rb +111 -0
  16. data/lib/puppet-herald/app/configuration.rb +70 -0
  17. data/lib/puppet-herald/app/frontend.rb +61 -0
  18. data/lib/puppet-herald/{views → app/views}/app.erb +5 -8
  19. data/lib/puppet-herald/{views → app/views}/err500.erb +1 -4
  20. data/lib/puppet-herald/application.rb +27 -0
  21. data/lib/puppet-herald/cli.rb +66 -45
  22. data/lib/puppet-herald/client.rb +33 -0
  23. data/lib/puppet-herald/database.rb +84 -40
  24. data/lib/puppet-herald/javascript.rb +23 -17
  25. data/lib/puppet-herald/models/log-entry.rb +10 -3
  26. data/lib/puppet-herald/models/node.rb +15 -5
  27. data/lib/puppet-herald/models/report.rb +70 -63
  28. data/lib/puppet-herald/public/app.js +9 -8
  29. data/lib/puppet-herald/public/components/directives/status-button.html +1 -1
  30. data/lib/puppet-herald/public/components/directives/status-button.js +5 -3
  31. data/lib/puppet-herald/public/components/filters/filters.js +9 -4
  32. data/lib/puppet-herald/public/components/page.js +34 -0
  33. data/lib/puppet-herald/public/node/node.html +3 -1
  34. data/lib/puppet-herald/public/node/node.js +7 -4
  35. data/lib/puppet-herald/public/nodes/nodes.js +3 -2
  36. data/lib/puppet-herald/public/report/report.html +4 -1
  37. data/lib/puppet-herald/public/report/report.js +5 -3
  38. data/lib/puppet-herald/stubs/puppet.rb +20 -9
  39. data/lib/puppet-herald/version.rb +17 -7
  40. data/package.json +8 -3
  41. data/puppet-herald.gemspec +3 -6
  42. data/spec/integration/application_spec.rb +175 -0
  43. data/spec/integration/models/node_spec.rb +4 -4
  44. data/spec/integration/models/report_spec.rb +7 -7
  45. data/spec/spec_helper.rb +12 -7
  46. data/spec/support/active_record.rb +6 -10
  47. data/spec/support/reconnectdb.rb +13 -0
  48. data/spec/unit/puppet-herald/cli_spec.rb +45 -13
  49. data/spec/unit/puppet-herald/client_spec.rb +23 -0
  50. data/spec/unit/puppet-herald/database_spec.rb +8 -9
  51. data/spec/unit/puppet-herald/javascript_spec.rb +8 -13
  52. data/spec/unit/puppet-herald_spec.rb +4 -4
  53. data/test/javascript/karma.conf.js +43 -5
  54. data/test/javascript/src/app_test.js +90 -0
  55. data/test/javascript/src/components/artifact/artifact-directive_test.js +36 -0
  56. data/test/javascript/src/components/artifact/artifact_test.js +64 -0
  57. data/test/javascript/src/components/directives/status-button_test.js +159 -0
  58. data/test/javascript/src/components/filters/filters_test.js +35 -0
  59. data/test/javascript/src/node/node_test.js +87 -0
  60. data/test/javascript/src/nodes/nodes_test.js +56 -0
  61. data/test/javascript/src/report/report_test.js +94 -0
  62. metadata +98 -68
  63. data/lib/puppet-herald/app.rb +0 -103
  64. data/lib/puppet-herald/public/components/artifact/artifact-directive_test.js +0 -17
  65. 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
- class Report < ActiveRecord::Base
6
- belongs_to :node
7
- has_many :log_entries, dependent: :delete_all
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
- def self.get_with_log_entries id
10
- Report.where("id = ?", id).includes(:log_entries).first
11
- end
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
- def self.create_from_yaml yaml
14
- parsed = parse_yaml yaml
15
- report = Report.new
16
-
17
- parse_properties parsed, report
18
- parse_logs parsed, report
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
- report.save
22
- node.save
23
- return report
24
- end
29
+ parse_properties parsed, report
30
+ parse_logs parsed, report
31
+ node = parse_node parsed, report
25
32
 
26
- private
33
+ report.save
34
+ node.save
35
+ report
36
+ end
27
37
 
28
- def self.parse_node parsed, report
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
- def self.parse_properties parsed, report
44
- attr_to_copy = [
45
- 'status', 'environment',
46
- 'transaction_uuid', 'time',
47
- 'puppet_version', 'kind',
48
- 'host', 'configuration_version'
49
- ]
50
- copy_attrs parsed, report, attr_to_copy
51
- end
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
- def self.parse_logs parsed, report
54
- parsed.logs.each do |in_log|
55
- log = LogEntry.new
56
- attr_to_copy = [
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
- def self.parse_yaml yaml
67
- require 'yaml'
68
- raw = YAML.parse yaml
69
- raw.to_ruby
70
- end
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
- def self.copy_attrs from, to, attrs
73
- attrs.each do |at|
74
- value = from.send at
75
- to.send "#{at}=", value
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.factory('appService', function() {
18
- return {
19
- page: 'home'
20
- };
21
- });
22
-
23
- app.controller('AppController', ['appService', function(appService) {
24
- this.page = appService.page;
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
  })();
@@ -3,5 +3,5 @@
3
3
  btn btn-xs btn-{{ status | colorizeStatus }}
4
4
  glyphicon glyphicon-{{ status | iconizeStatus }}
5
5
  "
6
- ng-click="navigate()"
6
+ ng-click="navigate(route, id)"
7
7
  aria-hidden="true"> {{ status | uppercase }}</button>
@@ -10,8 +10,8 @@
10
10
 
11
11
  $scope.$location = $location;
12
12
 
13
- $scope.navigate = function() {
14
- var target = this.route.replace(':id', this.id);
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
- default: return 'asterisk';
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 first = input.substring(0, 1);
9
- var rest = input.substring(1);
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 {{ ctrl.node.name }} <span class="badge">{{ ctrl.node.reports.length }}</span></div>
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.directives'
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/node/' + this.nodeId).success(function(data) {
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', 'appService', function($http, appService) {
17
- appService.page = 'nodes';
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 for {{ ctrl.report.host }} <span class="badge">{{ ctrl.report.log_entries.length }}</span></div>
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/report/' + this.reportId).success(function(data) {
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
- attr_accessor :host, :time, :kind, :puppet_version, :configuration_version, :transaction_uuid, :environment, :status, :logs
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
- def self.version_prep desired
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 += "." + git.gsub('-', '.')
11
+ version += '.' + git.gsub('-', '.')
8
12
  end
9
- return version.strip
13
+ version.strip
10
14
  end
11
15
 
12
- VERSION = version_prep '0.1.1'
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
- DESCRIPTION = "Provides a gateway for consuming puppet reports, a REST API and a simple Web app to display reports."
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