puppet-herald 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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