foreman_omaha 0.0.3 → 1.0.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 -5
- data/README.md +5 -2
- data/app/assets/javascripts/foreman_omaha/application.js +1 -0
- data/app/assets/stylesheets/foreman_omaha/version_breakdown.scss +13 -0
- data/app/controllers/api/v2/omaha_groups_controller.rb +29 -0
- data/app/controllers/api/v2/omaha_reports_controller.rb +9 -7
- data/app/controllers/omaha_groups_controller.rb +28 -0
- data/app/controllers/omaha_hosts_controller.rb +42 -0
- data/app/controllers/omaha_reports_controller.rb +0 -11
- data/app/helpers/concerns/foreman_omaha/hosts_helper_extensions.rb +15 -6
- data/app/helpers/foreman_omaha/application_helper.rb +7 -0
- data/app/helpers/foreman_omaha/omaha_groups_helper.rb +52 -0
- data/app/helpers/omaha_hosts_helper.rb +43 -0
- data/app/models/concerns/foreman_omaha/host_extensions.rb +16 -2
- data/app/models/concerns/foreman_omaha/omaha_facet_host_extensions.rb +23 -0
- data/app/models/foreman_omaha/omaha_facet.rb +40 -0
- data/app/models/foreman_omaha/omaha_group.rb +34 -0
- data/app/models/foreman_omaha/omaha_report.rb +13 -21
- data/app/models/host_status/omaha_status.rb +6 -16
- data/app/services/foreman_omaha/charts/oem_distribution.rb +24 -0
- data/app/services/foreman_omaha/charts/status_distribution.rb +57 -0
- data/app/services/foreman_omaha/charts/version_distribution.rb +24 -0
- data/app/services/foreman_omaha/container_linux_config_transpiler.rb +33 -0
- data/app/services/foreman_omaha/fact_parser.rb +19 -3
- data/app/services/foreman_omaha/group_version_breakdown.rb +30 -0
- data/app/services/foreman_omaha/omaha_report_importer.rb +52 -3
- data/app/services/foreman_omaha/renderer_methods.rb +7 -0
- data/app/services/foreman_omaha/status_mapper.rb +53 -0
- data/app/views/api/v2/omaha_groups/base.json.rabl +3 -0
- data/app/views/api/v2/omaha_groups/index.json.rabl +3 -0
- data/app/views/api/v2/omaha_groups/main.json.rabl +5 -0
- data/app/views/api/v2/omaha_groups/show.json.rabl +3 -0
- data/app/views/application/foreman_omaha/_toolbar.html.erb +11 -0
- data/app/views/foreman_omaha/api/v2/omaha_facets/base.json.rabl +5 -0
- data/app/views/foreman_omaha/api/v2/omaha_facets/base_with_root.json.rabl +3 -0
- data/app/views/foreman_omaha/api/v2/omaha_facets/show.json.rabl +3 -0
- data/app/views/hosts/_omaha_tab.html.erb +29 -0
- data/app/views/omaha_groups/index.html.erb +34 -0
- data/app/views/omaha_groups/show.html.erb +196 -0
- data/app/views/omaha_hosts/index.html.erb +51 -0
- data/app/views/omaha_hosts/welcome.html.erb +12 -0
- data/app/views/omaha_reports/_details.html.erb +5 -3
- data/app/views/omaha_reports/_list.html.erb +2 -2
- data/app/views/omaha_reports/show.html.erb +1 -1
- data/app/views/omaha_reports/welcome.html.erb +1 -1
- data/config/routes.rb +14 -1
- data/db/migrate/20160812083100_add_omaha_fields_to_reports.foreman_omaha.rb +1 -1
- data/db/migrate/20171101204100_create_omaha_facets.foreman_omaha.rb +22 -0
- data/db/seeds.d/200_omaha_groups.rb +6 -0
- data/lib/foreman_omaha/engine.rb +74 -21
- data/lib/foreman_omaha/version.rb +1 -1
- data/lib/tasks/foreman_omaha_tasks.rake +2 -4
- data/test/factories/feature.rb +1 -1
- data/test/factories/foreman_omaha_factories.rb +16 -1
- data/test/factories/host.rb +21 -0
- data/test/factories/smart_proxy.rb +1 -1
- data/test/functional/api/v2/omaha_groups_controller_test.rb +32 -0
- data/test/functional/api/v2/omaha_reports_controller_test.rb +24 -24
- data/test/functional/omaha_groups_controller_test.rb +18 -0
- data/test/functional/omaha_hosts_controller_test.rb +11 -0
- data/test/functional/omaha_reports_controller_test.rb +13 -13
- data/test/test_plugin_helper.rb +3 -3
- data/test/unit/charts/oem_distribution_test.rb +26 -0
- data/test/unit/charts/status_distribution_test.rb +28 -0
- data/test/unit/charts/version_distribution_test.rb +28 -0
- data/test/unit/group_version_breakdown_test.rb +65 -0
- data/test/unit/host_status/omaha_status_test.rb +19 -0
- data/test/unit/host_test.rb +55 -0
- data/test/unit/omaha_fact_parser_test.rb +77 -0
- data/test/unit/omaha_report_test.rb +63 -17
- data/test/unit/renderer_test.rb +21 -0
- metadata +80 -9
@@ -0,0 +1,34 @@
|
|
1
|
+
module ForemanOmaha
|
2
|
+
class OmahaGroup < ApplicationRecord
|
3
|
+
include Authorizable
|
4
|
+
|
5
|
+
def self.humanize_class_name
|
6
|
+
N_('Omaha Channel')
|
7
|
+
end
|
8
|
+
|
9
|
+
has_many :omaha_facets, :class_name => 'ForemanOmaha::OmahaFacet', :foreign_key => :omaha_group_id,
|
10
|
+
:inverse_of => :omaha_group, :dependent => :restrict_with_exception
|
11
|
+
has_many :hosts, :class_name => '::Host::Managed', :through => :omaha_facets,
|
12
|
+
:inverse_of => :omaha_group
|
13
|
+
|
14
|
+
scoped_search :on => :name, :complete_value => :true, :default_order => true
|
15
|
+
|
16
|
+
validates_lengths_from_database
|
17
|
+
|
18
|
+
before_validation :ensure_uuid
|
19
|
+
|
20
|
+
def operatingsystems
|
21
|
+
Coreos.where(:release_name => name.downcase)
|
22
|
+
end
|
23
|
+
|
24
|
+
def latest_operatingsystem
|
25
|
+
operatingsystems.order(:major, :minor).last
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def ensure_uuid
|
31
|
+
self.uuid ||= SecureRandom.uuid
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module ForemanOmaha
|
2
2
|
class OmahaReport < ::Report
|
3
|
-
enum :status =>
|
4
|
-
:installed, :instance_hold, :error]
|
3
|
+
enum :status => OmahaFacet::VALID_OMAHA_STATUSES
|
5
4
|
|
6
5
|
scoped_search :on => :omaha_version, :rename => :version, :complete_value => true
|
7
6
|
scoped_search :on => :status, :complete_value => statuses
|
@@ -14,25 +13,12 @@ module ForemanOmaha
|
|
14
13
|
'status'
|
15
14
|
end
|
16
15
|
|
17
|
-
def
|
18
|
-
|
19
|
-
when :complete
|
20
|
-
_('Complete')
|
21
|
-
when :downloading
|
22
|
-
_('Downloading')
|
23
|
-
when :downloaded
|
24
|
-
_('Downloaded')
|
25
|
-
when :installed
|
26
|
-
_('Installed')
|
27
|
-
when :instance_hold
|
28
|
-
_('Instance Hold')
|
29
|
-
when :error
|
30
|
-
_('Error')
|
31
|
-
else
|
32
|
-
_('unknown')
|
33
|
-
end
|
16
|
+
def self.humanize_class_name
|
17
|
+
N_('Omaha Report')
|
34
18
|
end
|
35
19
|
|
20
|
+
delegate :to_label, :to_description, :to => :status_mapper
|
21
|
+
|
36
22
|
def operatingsystem
|
37
23
|
return if omaha_version.blank?
|
38
24
|
args = { :type => 'Coreos', :major => osmajor, :minor => osminor }
|
@@ -41,14 +27,20 @@ module ForemanOmaha
|
|
41
27
|
|
42
28
|
def osmajor
|
43
29
|
omaha_version.gsub(/^(\d+)\.\d\.\d$/, '\1')
|
44
|
-
rescue
|
30
|
+
rescue StandardError
|
45
31
|
nil
|
46
32
|
end
|
47
33
|
|
48
34
|
def osminor
|
49
35
|
omaha_version.gsub(/^\d+\.(\d\.\d)$/, '\1')
|
50
|
-
rescue
|
36
|
+
rescue StandardError
|
51
37
|
nil
|
52
38
|
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def status_mapper
|
43
|
+
StatusMapper.new(status)
|
44
|
+
end
|
53
45
|
end
|
54
46
|
end
|
@@ -1,27 +1,17 @@
|
|
1
1
|
module HostStatus
|
2
2
|
class OmahaStatus < HostStatus::Status
|
3
|
-
def last_report
|
4
|
-
self.last_report = host.last_omaha_report_object unless @last_report_set
|
5
|
-
@last_report
|
6
|
-
end
|
7
|
-
|
8
|
-
def last_report=(report)
|
9
|
-
@last_report_set = true
|
10
|
-
@last_report = report
|
11
|
-
end
|
12
|
-
|
13
3
|
def self.status_name
|
14
4
|
N_('Omaha Status')
|
15
5
|
end
|
16
6
|
|
17
7
|
def to_status(_options = {})
|
18
|
-
return ::ForemanOmaha::
|
19
|
-
::ForemanOmaha::
|
8
|
+
return ::ForemanOmaha::OmahaFacet.statuses[:unknown] unless relevant?
|
9
|
+
::ForemanOmaha::OmahaFacet.statuses[host.omaha_facet.status]
|
20
10
|
end
|
21
11
|
|
22
12
|
def to_global(_options = {})
|
23
|
-
return ::ForemanOmaha::
|
24
|
-
case
|
13
|
+
return ::ForemanOmaha::OmahaFacet.statuses[:unknown] unless relevant?
|
14
|
+
case host.omaha_facet.status.to_sym
|
25
15
|
when :complete, :downloaded, :downloading, :installed
|
26
16
|
HostStatus::Global::OK
|
27
17
|
when :instance_hold
|
@@ -34,11 +24,11 @@ module HostStatus
|
|
34
24
|
end
|
35
25
|
|
36
26
|
def to_label(_options = {})
|
37
|
-
|
27
|
+
host.omaha_facet.to_status_label
|
38
28
|
end
|
39
29
|
|
40
30
|
def relevant?(_options = {})
|
41
|
-
host &&
|
31
|
+
host && !!host.omaha_facet
|
42
32
|
end
|
43
33
|
end
|
44
34
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module ForemanOmaha
|
2
|
+
module Charts
|
3
|
+
class OemDistribution
|
4
|
+
attr_accessor :hosts
|
5
|
+
|
6
|
+
def initialize(hosts = nil)
|
7
|
+
@hosts = hosts || Host.authorized(:view_hosts, Host).joins(:omaha_facet)
|
8
|
+
end
|
9
|
+
|
10
|
+
def query
|
11
|
+
@query ||= hosts.group(:oem).count
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_chart_data
|
15
|
+
query.map do |oem, count|
|
16
|
+
{
|
17
|
+
:label => oem,
|
18
|
+
:data => count
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module ForemanOmaha
|
2
|
+
module Charts
|
3
|
+
class StatusDistribution
|
4
|
+
attr_accessor :hosts
|
5
|
+
|
6
|
+
def initialize(hosts = nil)
|
7
|
+
@hosts = hosts || Host.authorized(:view_hosts, Host).joins(:omaha_facet)
|
8
|
+
end
|
9
|
+
|
10
|
+
def query
|
11
|
+
@query ||= hosts.group(:status).count.transform_keys { |k| ForemanOmaha::OmahaFacet.statuses.key(k).to_sym }
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_chart_data
|
15
|
+
query.map do |status, count|
|
16
|
+
{
|
17
|
+
:label => status_label(status),
|
18
|
+
:data => count,
|
19
|
+
:color => status_color(status)
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_a
|
25
|
+
query.map do |status, count|
|
26
|
+
{
|
27
|
+
:status => status,
|
28
|
+
:label => status_label(status),
|
29
|
+
:count => count
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def color_map
|
37
|
+
{
|
38
|
+
:unknown => '#92A8CD',
|
39
|
+
:complete => '#89A54E',
|
40
|
+
:downloading => '#3D96AE',
|
41
|
+
:downloaded => '#4572A7',
|
42
|
+
:installed => '#DB843D',
|
43
|
+
:instance_hold => '#80699B',
|
44
|
+
:error => '#AA4643'
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def status_color(status)
|
49
|
+
color_map[status]
|
50
|
+
end
|
51
|
+
|
52
|
+
def status_label(status)
|
53
|
+
ForemanOmaha::StatusMapper.new(status).to_label
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module ForemanOmaha
|
2
|
+
module Charts
|
3
|
+
class VersionDistribution
|
4
|
+
attr_accessor :hosts
|
5
|
+
|
6
|
+
def initialize(hosts = nil)
|
7
|
+
@hosts = hosts || Host.authorized(:view_hosts, Host).joins(:omaha_facet)
|
8
|
+
end
|
9
|
+
|
10
|
+
def query
|
11
|
+
hosts.group(:version).count
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_chart_data
|
15
|
+
query.map do |version, count|
|
16
|
+
{
|
17
|
+
:label => version,
|
18
|
+
:data => count
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
module ForemanOmaha
|
4
|
+
class ContainerLinuxConfigTranspiler
|
5
|
+
class TranspilerNotFound < StandardError; end
|
6
|
+
class TranspileError < StandardError; end
|
7
|
+
|
8
|
+
attr_accessor :input, :output, :errors, :status
|
9
|
+
|
10
|
+
def initialize(input)
|
11
|
+
self.input = input
|
12
|
+
end
|
13
|
+
|
14
|
+
def run!
|
15
|
+
check_transpiler
|
16
|
+
transpile
|
17
|
+
raise TranspileError, "Could not transpile container linux config to ignition: #{errors}" unless status.success?
|
18
|
+
output
|
19
|
+
end
|
20
|
+
|
21
|
+
def transpile
|
22
|
+
self.output, self.errors, self.status = Open3.capture3(cmd, :stdin_data => input)
|
23
|
+
end
|
24
|
+
|
25
|
+
def check_transpiler
|
26
|
+
raise TranspilerNotFound, 'The ct binary was not found in your PATH.' if cmd.blank?
|
27
|
+
end
|
28
|
+
|
29
|
+
def cmd
|
30
|
+
@cmd ||= Foreman::Util.which('ct')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -3,9 +3,9 @@ module ForemanOmaha
|
|
3
3
|
def operatingsystem
|
4
4
|
args = { :name => facts['platform'], :major => facts['osmajor'], :minor => facts['osminor'] }
|
5
5
|
description = "#{facts['platform']} #{facts['version']}"
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
Coreos.where(args).first ||
|
7
|
+
create_coreos_version(args.merge(:description => description,
|
8
|
+
:release_name => facts['track']))
|
9
9
|
end
|
10
10
|
|
11
11
|
def architecture
|
@@ -28,5 +28,21 @@ module ForemanOmaha
|
|
28
28
|
def support_interfaces_parsing?
|
29
29
|
false
|
30
30
|
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def create_coreos_version(attrs)
|
35
|
+
previous_version = previous_coreos_version
|
36
|
+
return Coreos.create!(attrs) unless previous_coreos_version
|
37
|
+
os = previous_version.deep_clone(
|
38
|
+
:include => [:ptables, :media, :os_default_templates, :architectures]
|
39
|
+
)
|
40
|
+
os.update_attributes(attrs)
|
41
|
+
os
|
42
|
+
end
|
43
|
+
|
44
|
+
def previous_coreos_version
|
45
|
+
Coreos.all.sort_by { |os| Gem::Version.new(os.release) }.last
|
46
|
+
end
|
31
47
|
end
|
32
48
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module ForemanOmaha
|
2
|
+
class GroupVersionBreakdown
|
3
|
+
attr_accessor :omaha_group
|
4
|
+
|
5
|
+
def initialize(opts = {})
|
6
|
+
self.omaha_group = opts.fetch(:omaha_group)
|
7
|
+
end
|
8
|
+
|
9
|
+
def version_breakdown
|
10
|
+
facets.group(:version).count.sort_by { |version, _| Gem::Version.new(version) }.reverse.map do |version, count|
|
11
|
+
{
|
12
|
+
:version => version,
|
13
|
+
:count => count,
|
14
|
+
:percentage => percentage(count)
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def facets
|
20
|
+
ForemanOmaha::OmahaFacet.where(:omaha_group => omaha_group)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def percentage(count)
|
26
|
+
return 0 if count.zero? || facets.count.zero?
|
27
|
+
(count.to_f * 100 / facets.count).round(2)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -10,19 +10,68 @@ module ForemanOmaha
|
|
10
10
|
|
11
11
|
private
|
12
12
|
|
13
|
+
def host
|
14
|
+
@host ||= ForemanOmaha::OmahaFacet.find_by(:machineid => machineid).try(:host) if machineid.present?
|
15
|
+
@name ||= @host.try(:name)
|
16
|
+
@host || super
|
17
|
+
end
|
18
|
+
|
13
19
|
def create_report_and_logs
|
14
20
|
super
|
15
|
-
|
16
|
-
|
17
|
-
|
21
|
+
return report unless report.persisted?
|
22
|
+
report.omaha_version = omaha_version
|
23
|
+
report.save
|
24
|
+
update_omaha_facet!
|
25
|
+
report
|
26
|
+
end
|
27
|
+
|
28
|
+
def omaha_facet
|
29
|
+
host.omaha_facet || host.build_omaha_facet
|
30
|
+
end
|
31
|
+
|
32
|
+
def update_omaha_facet!
|
33
|
+
return unless omaha_facet.last_report.nil? || omaha_facet.last_report.utc < time
|
34
|
+
omaha_facet.update(
|
35
|
+
:last_report => time,
|
36
|
+
:status => report_status,
|
37
|
+
:machineid => machineid,
|
38
|
+
:oem => oem,
|
39
|
+
:version => omaha_version,
|
40
|
+
:omaha_group => omaha_group
|
41
|
+
)
|
18
42
|
end
|
19
43
|
|
20
44
|
def report_status
|
21
45
|
raw['status']
|
22
46
|
end
|
23
47
|
|
48
|
+
def machineid
|
49
|
+
raw['machineid']
|
50
|
+
end
|
51
|
+
|
52
|
+
def oem
|
53
|
+
raw['oem']
|
54
|
+
end
|
55
|
+
|
24
56
|
def omaha_version
|
25
57
|
raw['omaha_version'] || 'unknown'
|
26
58
|
end
|
59
|
+
|
60
|
+
def omaha_group
|
61
|
+
ForemanOmaha::OmahaGroup.find_by(:uuid => raw['omaha_group']) || find_omaha_group_by_version
|
62
|
+
end
|
63
|
+
|
64
|
+
# If the Report does not contain information
|
65
|
+
# about the Omaha Group, we try to find
|
66
|
+
# the correct group by looking at the defined
|
67
|
+
# operating systems
|
68
|
+
def find_omaha_group_by_version
|
69
|
+
version = Gem::Version.new(omaha_version)
|
70
|
+
major = version.segments.first
|
71
|
+
minor = version.segments.last(2).join('.')
|
72
|
+
os = Coreos.find_by(:major => major, :minor => minor)
|
73
|
+
return unless os
|
74
|
+
ForemanOmaha::OmahaGroup.find_by(:uuid => os.release_name)
|
75
|
+
end
|
27
76
|
end
|
28
77
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module ForemanOmaha
|
2
|
+
class StatusMapper
|
3
|
+
attr_accessor :status
|
4
|
+
|
5
|
+
def initialize(status)
|
6
|
+
@status = status
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_label
|
10
|
+
case status.to_sym
|
11
|
+
when :complete
|
12
|
+
N_('Complete')
|
13
|
+
when :downloading
|
14
|
+
N_('Downloading')
|
15
|
+
when :downloaded
|
16
|
+
N_('Downloaded')
|
17
|
+
when :installed
|
18
|
+
N_('Installed')
|
19
|
+
when :instance_hold
|
20
|
+
N_('Instance Hold')
|
21
|
+
when :error
|
22
|
+
N_('Error')
|
23
|
+
else
|
24
|
+
N_('unknown')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
29
|
+
def to_description(version = nil)
|
30
|
+
case status.to_sym
|
31
|
+
when :complete
|
32
|
+
if version.present?
|
33
|
+
_('The host has been updated successfully and is now running version %s.') % version
|
34
|
+
else
|
35
|
+
_('The host has been updated successfully.')
|
36
|
+
end
|
37
|
+
when :downloading
|
38
|
+
_('The host has just started downloading the update package.')
|
39
|
+
when :downloaded
|
40
|
+
_('The host has downloaded the update package and will install it now.')
|
41
|
+
when :installed
|
42
|
+
_('The host has installed the update package but is not using it yet.')
|
43
|
+
when :instance_hold
|
44
|
+
_('An update for this host is pending but it was put on hold because of the rollout policy.')
|
45
|
+
when :error
|
46
|
+
_('The host reported an error while updating.')
|
47
|
+
else
|
48
|
+
_('The status of this host is unknown.')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
52
|
+
end
|
53
|
+
end
|