foreman_openscap 0.5.0 → 0.5.1

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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/foreman_openscap/arf_reports.js +16 -0
  3. data/app/assets/javascripts/foreman_openscap/openscap_proxy.js +52 -0
  4. data/app/assets/javascripts/foreman_openscap/reports.js +6 -0
  5. data/app/assets/stylesheets/foreman_openscap/policy.css +2 -1
  6. data/app/assets/stylesheets/foreman_openscap/reports.css +3 -0
  7. data/app/controllers/api/v2/compliance/arf_reports_controller.rb +2 -2
  8. data/app/controllers/api/v2/compliance/policies_controller.rb +6 -6
  9. data/app/controllers/api/v2/compliance/scap_contents_controller.rb +2 -2
  10. data/app/controllers/arf_reports_controller.rb +41 -5
  11. data/app/controllers/concerns/foreman_openscap/hostgroups_controller_extensions.rb +20 -0
  12. data/app/controllers/concerns/foreman_openscap/hosts_common_controller_extensions.rb +45 -0
  13. data/app/controllers/concerns/foreman_openscap/hosts_controller_extensions.rb +17 -0
  14. data/app/controllers/policies_controller.rb +4 -4
  15. data/app/helpers/arf_report_dashboard_helper.rb +5 -5
  16. data/app/helpers/arf_reports_helper.rb +28 -0
  17. data/app/helpers/compliance_hosts_helper.rb +5 -3
  18. data/app/helpers/policies_helper.rb +3 -3
  19. data/app/helpers/policy_dashboard_helper.rb +2 -2
  20. data/app/lib/proxy_api/available_proxy.rb +7 -7
  21. data/app/lib/proxy_api/openscap.rb +10 -0
  22. data/app/mailers/foreman_openscap/policy_mailer.rb +2 -2
  23. data/app/models/concerns/foreman_openscap/compliance_status_scoped_search.rb +5 -5
  24. data/app/models/concerns/foreman_openscap/host_extensions.rb +22 -14
  25. data/app/models/concerns/foreman_openscap/hostgroup_extensions.rb +12 -0
  26. data/app/models/concerns/foreman_openscap/log_extensions.rb +8 -0
  27. data/app/models/concerns/foreman_openscap/openscap_proxy_core_extensions.rb +55 -0
  28. data/app/models/concerns/foreman_openscap/openscap_proxy_extensions.rb +17 -0
  29. data/app/models/concerns/foreman_openscap/smart_proxy_extensions.rb +23 -0
  30. data/app/models/foreman_openscap/arf_report.rb +42 -21
  31. data/app/models/foreman_openscap/policy.rb +38 -38
  32. data/app/models/foreman_openscap/scap_content.rb +9 -9
  33. data/app/overrides/hostgroups/form/select_openscap_proxy.rb +4 -0
  34. data/app/overrides/hosts/form/select_openscap_proxy.rb +4 -0
  35. data/app/services/foreman_openscap/host_report_dashboard/data.rb +5 -5
  36. data/app/services/foreman_openscap/report_dashboard/data.rb +5 -5
  37. data/app/views/arf_reports/_detailed_message.html.erb +9 -0
  38. data/app/views/arf_reports/_list.html.erb +29 -9
  39. data/app/views/arf_reports/_output.html.erb +12 -8
  40. data/app/views/arf_reports/delete_multiple.html.erb +29 -0
  41. data/app/views/arf_reports/index.html.erb +1 -1
  42. data/app/views/arf_reports/show.html.erb +3 -1
  43. data/app/views/compliance_hosts/_openscap_proxy.html.erb +8 -0
  44. data/app/views/policies/_form.html.erb +1 -1
  45. data/app/views/policies/steps/_schedule_form.html.erb +1 -1
  46. data/config/routes.rb +17 -1
  47. data/db/migrate/20141013172051_create_scaptimony_policies.rb +1 -1
  48. data/db/migrate/20141014105333_create_scaptimony_assets.rb +2 -2
  49. data/db/migrate/20141015092642_create_scaptimony_arf_reports.rb +4 -4
  50. data/db/migrate/20141104164201_create_scaptimony_scap_contents.rb +1 -3
  51. data/db/migrate/20141104171545_create_scaptimony_policy_revisions.rb +2 -2
  52. data/db/migrate/20141105174834_add_columns_to_scaptimony_policies.rb +1 -1
  53. data/db/migrate/20141113221054_create_scaptimony_scap_content_profiles.rb +1 -1
  54. data/db/migrate/20141116171305_add_profile_to_scaptimony_policies.rb +1 -1
  55. data/db/migrate/20141119182606_create_scaptimony_xccdf_rule_results.rb +3 -3
  56. data/db/migrate/20150821100137_migrate_from_scaptimony.rb +2 -2
  57. data/db/migrate/20150929152345_move_arf_reports_to_reports_table.rb +1 -1
  58. data/db/migrate/20151023131950_link_arf_report_directly_to_host.rb +12 -8
  59. data/db/migrate/20151118165125_add_size_to_scap_content.rb +5 -0
  60. data/db/migrate/20151119155419_add_arf_fields_to_message.rb +8 -0
  61. data/db/migrate/20151120090851_add_openscap_proxy_to_host_and_hostgroup.rb +25 -0
  62. data/db/seeds.d/openscap_feature.rb +1 -1
  63. data/db/seeds.d/openscap_scap_default.rb +1 -1
  64. data/lib/foreman_openscap/bulk_upload.rb +11 -12
  65. data/lib/foreman_openscap/engine.rb +22 -11
  66. data/lib/foreman_openscap/helper.rb +1 -1
  67. data/lib/foreman_openscap/version.rb +1 -1
  68. data/lib/tasks/foreman_openscap_tasks.rake +3 -2
  69. data/test/factories/arf_report_factory.rb +2 -1
  70. data/test/factories/compliance_host_factory.rb +1 -0
  71. data/test/factories/scap_content_related.rb +1 -1
  72. data/test/functional/api/v2/compliance/arf_reports_controller_test.rb +3 -3
  73. data/test/functional/api/v2/compliance/policies_controller_test.rb +1 -1
  74. data/test/functional/api/v2/compliance/scap_contents_controller_test.rb +2 -2
  75. data/test/functional/arf_reports_controller_test.rb +21 -0
  76. data/test/lib/foreman_openscap/bulk_upload_test.rb +2 -2
  77. data/test/test_plugin_helper.rb +2 -2
  78. data/test/unit/arf_report_test.rb +12 -1
  79. data/test/unit/compliance_status_test.rb +6 -5
  80. data/test/unit/openscap_host_test.rb +4 -0
  81. data/test/unit/policy_mailer_test.rb +1 -1
  82. data/test/unit/scap_content_test.rb +1 -1
  83. metadata +29 -8
@@ -26,9 +26,9 @@ module PolicyDashboardHelper
26
26
  [:incompliant_hosts, _('Incompliant hosts')],
27
27
  [:inconclusive_hosts, _('Inconclusive')],
28
28
  [:report_missing, _('Not audited')],
29
- ].each { |i|
29
+ ].each do |i|
30
30
  data << {:label => i[1], :data => report[i[0]], :color => COLORS[i[0]]}
31
- }
31
+ end
32
32
  flot_pie_chart 'overview', _('Compliance Status'), data, options
33
33
  end
34
34
 
@@ -2,13 +2,13 @@ module ::ProxyAPI
2
2
  class AvailableProxy
3
3
 
4
4
  HTTP_ERRORS = [
5
- EOFError,
6
- Errno::ECONNRESET,
7
- Errno::EINVAL,
8
- Net::HTTPBadResponse,
9
- Net::HTTPHeaderSyntaxError,
10
- Net::ProtocolError,
11
- Timeout::Error
5
+ EOFError,
6
+ Errno::ECONNRESET,
7
+ Errno::EINVAL,
8
+ Net::HTTPBadResponse,
9
+ Net::HTTPHeaderSyntaxError,
10
+ Net::ProtocolError,
11
+ Timeout::Error
12
12
  ]
13
13
 
14
14
  def initialize(args)
@@ -36,5 +36,15 @@ module ::ProxyAPI
36
36
  raise ::ProxyAPI::ProxyException.new(url, e, N_("Unable to get xml version of requested report from Smart Proxy"))
37
37
  end
38
38
  end
39
+
40
+ def destroy_report(report, cname)
41
+ begin
42
+ parse(delete("arf/#{report.id}/#{cname}/#{report.reported_at.to_i}/#{report.policy_arf_report.digest}"))
43
+ rescue => e
44
+ logger.error "Failed to destroy arf report with id #{report.id} on Smart Proxy"
45
+ logger.debug e.backtrace.join("\n\t")
46
+ false
47
+ end
48
+ end
39
49
  end
40
50
  end
@@ -1,12 +1,12 @@
1
1
  module ForemanOpenscap
2
- class PolicyMailer < ::ApplicationMailer
2
+ class PolicyMailer < ::ApplicationMailer
3
3
 
4
4
  def policy_summary(options = {})
5
5
  set_url
6
6
  user = ::User.find(options[:user])
7
7
  @time = options[:time] || 1.day.ago
8
8
 
9
- @policies = ::ForemanOpenscap::Policy.all.reject {|policy| policy.assets.map(&:host).compact.empty?}
9
+ @policies = ::ForemanOpenscap::Policy.all.reject { |policy| policy.assets.map(&:host).compact.empty? }
10
10
  @compliant_hosts = @policies.map { |policy| Host.where(:id => policy.assets.comply_with(policy).map(&:assetable_id)) }.flatten
11
11
  @incompliant_hosts = @policies.map { |policy| Host.where(:id => policy.assets.incomply_with(policy).map(&:assetable_id)) }.flatten
12
12
  changed_hosts_of_policies(@policies)
@@ -11,9 +11,9 @@ module ForemanOpenscap
11
11
  def search_by_policy_name(_key, _operator, policy_name)
12
12
  cond = sanitize_policy_name(policy_name)
13
13
  { :conditions => ArfReport.arel_table[:id].in(
14
- PolicyArfReport.select(PolicyArfReport.arel_table[:arf_report_id])
15
- .of_policy(Policy.find_by_name(cond).id).ast
16
- ).to_sql
14
+ PolicyArfReport.select(PolicyArfReport.arel_table[:arf_report_id])
15
+ .of_policy(Policy.find_by_name(cond).id).ast
16
+ ).to_sql
17
17
  }
18
18
  end
19
19
 
@@ -29,12 +29,12 @@ module ForemanOpenscap
29
29
  search_by_policy_results policy_name, &:othered
30
30
  end
31
31
 
32
- def search_by_policy_results(policy_name, &selection)
32
+ def search_by_policy_results(policy_name, &selection)
33
33
  cond = sanitize_policy_name(policy_name)
34
34
  { :conditions => ArfReport.arel_table[:id].in(
35
35
  ArfReport.select(ArfReport.arel_table[:id])
36
36
  .latest_of_policy(Policy.find_by_name cond).instance_eval(&selection).ast
37
- ).to_sql
37
+ ).to_sql
38
38
  }
39
39
  end
40
40
 
@@ -10,16 +10,17 @@ module ForemanOpenscap
10
10
  has_many :arf_reports, :class_name => '::ForemanOpenscap::ArfReport', :foreign_key => :host_id
11
11
  has_one :compliance_status_object, :class_name => '::ForemanOpenscap::ComplianceStatus', :foreign_key => 'host_id'
12
12
 
13
- scoped_search :in => :policies, :on => :name, :complete_value => true, :rename => :'compliance_policy',
13
+ scoped_search :in => :policies, :on => :name, :complete_value => true, :rename => :compliance_policy,
14
14
  :only_explicit => true, :operators => ['= ', '!= '], :ext_method => :search_by_policy_name
15
15
 
16
- scoped_search :in => :policies, :on => :name, :complete_value => true, :rename => :'compliance_report_missing_for',
16
+ scoped_search :in => :policies, :on => :name, :complete_value => true, :rename => :compliance_report_missing_for,
17
17
  :only_explicit => true, :operators => ['= ', '!= '], :ext_method => :search_by_missing_arf
18
18
 
19
19
  scoped_search :in => :compliance_status_object, :on => :status, :rename => :compliance_status,
20
20
  :complete_value => {:compliant => ::ForemanOpenscap::ComplianceStatus::COMPLIANT,
21
21
  :incompliant => ::ForemanOpenscap::ComplianceStatus::INCOMPLIANT,
22
22
  :inconclusive => ::ForemanOpenscap::ComplianceStatus::INCONCLUSIVE}
23
+ after_save :puppetrun!, :if => :openscap_proxy_id_changed?
23
24
 
24
25
  scope :comply_with, lambda { |policy|
25
26
  joins(:arf_reports).merge(ArfReport.latest_of_policy policy).merge(ArfReport.passed)
@@ -44,6 +45,14 @@ module ForemanOpenscap
44
45
  WHERE foreman_openscap_assets.assetable_type = 'Host::Base'
45
46
  AND foreman_openscap_asset_policies.policy_id = '#{policy.id}')")
46
47
  }
48
+
49
+ alias_method_chain :set_hostgroup_defaults, :openscap
50
+ end
51
+
52
+ def set_hostgroup_defaults_with_openscap
53
+ set_hostgroup_defaults_without_openscap
54
+ return unless hostgroup
55
+ assign_hostgroup_attributes %w(openscap_proxy_id)
47
56
  end
48
57
 
49
58
  def get_asset
@@ -91,25 +100,24 @@ module ForemanOpenscap
91
100
  def search_by_policy_name(key, operator, policy_name)
92
101
  cond = sanitize_sql_for_conditions(["foreman_openscap_policies.name #{operator} ?", value_to_sql(operator, policy_name)])
93
102
  { :conditions => Host::Managed.arel_table[:id].in(
94
- Host::Managed.select(Host::Managed.arel_table[:id]).joins(:policies).where(cond).ast
95
- ).to_sql }
103
+ Host::Managed.select(Host::Managed.arel_table[:id]).joins(:policies).where(cond).ast
104
+ ).to_sql }
96
105
  end
97
106
 
98
107
  def search_by_missing_arf(key, operator, policy_name)
99
108
  cond = sanitize_sql_for_conditions(["foreman_openscap_policies.name #{operator} ?", value_to_sql(operator, policy_name)])
100
109
  { :conditions => Host::Managed.arel_table[:id].in(
101
- Host::Managed.select(Host::Managed.arel_table[:id])
102
- .joins(:policies)
103
- .where(cond)
104
- .where("foreman_openscap_assets.id NOT IN (
105
- SELECT DISTINCT foreman_openscap_arf_reports.asset_id
106
- FROM foreman_openscap_arf_reports
107
- WHERE foreman_openscap_arf_reports.asset_id = foreman_openscap_assets.id
108
- AND foreman_openscap_arf_reports.policy_id = foreman_openscap_policies.id)
109
- ").ast).to_sql
110
+ Host::Managed.select(Host::Managed.arel_table[:id])
111
+ .joins(:policies)
112
+ .where(cond)
113
+ .where("foreman_openscap_assets.id NOT IN (
114
+ SELECT DISTINCT foreman_openscap_arf_reports.asset_id
115
+ FROM foreman_openscap_arf_reports
116
+ WHERE foreman_openscap_arf_reports.asset_id = foreman_openscap_assets.id
117
+ AND foreman_openscap_arf_reports.policy_id = foreman_openscap_policies.id)
118
+ ").ast).to_sql
110
119
  }
111
120
  end
112
-
113
121
  end
114
122
  end
115
123
  end
@@ -7,5 +7,17 @@ module ForemanOpenscap
7
7
  has_many :asset_policies, :through => :asset, :class_name => "::ForemanOpenscap::AssetPolicy"
8
8
  has_many :policies, :through => :asset_policies, :class_name => "::ForemanOpenscap::Policy"
9
9
  end
10
+
11
+ unless defined?(Katello::System)
12
+ private
13
+
14
+ def inherited_ancestry_attribute(attribute)
15
+ if ancestry.present?
16
+ self[attribute] || self.class.sort_by_ancestry(ancestors.where("#{attribute} is not NULL")).last.try(attribute)
17
+ else
18
+ self.send(attribute)
19
+ end
20
+ end
21
+ end
10
22
  end
11
23
  end
@@ -0,0 +1,8 @@
1
+ module ForemanOpenscap
2
+ module LogExtensions
3
+ extend ActiveSupport::Concern
4
+ included do
5
+ attr_accessible :result
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,55 @@
1
+ module ForemanOpenscap
2
+ module OpenscapProxyCoreExtensions
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ validate :openscap_proxy_has_feature
7
+ end
8
+
9
+ def update_scap_client_params(proxy_id)
10
+ new_proxy = SmartProxy.find proxy_id
11
+ model_match = self.class.name.underscore.match(/\Ahostgroup\z/) ? "hostgroup" : "fqdn"
12
+ puppetclass = Puppetclass.find_by_name("foreman_scap_client")
13
+ fail _("Puppetclass 'foreman_scap_client' not found, make sure it is imported form Puppetmaster") if puppetclass.nil?
14
+ scap_params = puppetclass.class_params
15
+ server_lookup_key = scap_params.find { |param| param.key == "server" }
16
+ port_lookup_key = scap_params.find { |param| param.key == "port" }
17
+ pairs = scap_client_lookup_values_for([server_lookup_key, port_lookup_key], model_match)
18
+ mapping = { "server" => new_proxy.hostname, "port" => new_proxy.port }
19
+ update_scap_client_lookup_values(pairs, model_match, mapping)
20
+ end
21
+
22
+ def inherited_openscap_proxy_id
23
+ inherited_ancestry_attribute(:openscap_proxy_id)
24
+ end
25
+
26
+ private
27
+
28
+ def scap_client_lookup_values_for(lookup_keys, model_match)
29
+ lookup_keys.inject({}) do |result, key|
30
+ result[key] = key.lookup_values.find { |value| value.match == "#{lookup_matcher(model_match)}" }
31
+ result
32
+ end
33
+ end
34
+
35
+ def update_scap_client_lookup_values(pairs, model_match, mapping)
36
+ pairs.each do |k, v|
37
+ if v.nil?
38
+ LookupValue.create(:match => lookup_matcher(model_match), :value => mapping[k.key], :lookup_key_id => k.id)
39
+ else
40
+ v.value = mapping[k.key]
41
+ v.save
42
+ end
43
+ end
44
+ end
45
+
46
+ def lookup_matcher(model_match)
47
+ model_match == "fqdn" ? "#{model_match}=#{name}" : "#{model_match}=#{title}"
48
+ end
49
+
50
+ def openscap_proxy_has_feature
51
+ return true unless openscap_proxy_id
52
+ openscap_proxy.has_feature? "Openscap"
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,17 @@
1
+ module ForemanOpenscap
2
+ module OpenscapProxyExtensions
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ belongs_to :openscap_proxy, :class_name => "SmartProxy"
7
+ attr_accessible :openscap_proxy_id
8
+ end
9
+
10
+ def openscap_proxy_api
11
+ return @openscap_api if @openscap_api
12
+ proxy_url = openscap_proxy.url if openscap_proxy
13
+ fail(_("No openscap proxy found for %s") % id) unless proxy_url
14
+ @openscap_api = ::ProxyAPI::Openscap.new(:url => proxy_url)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ module ForemanOpenscap
2
+ module SmartProxyExtensions
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ has_many :openscap_hostgroups, :foreign_key => 'openscap_proxy_id', :class_name => "::Hostgroup"
7
+ has_many :openscap_hosts, :foreign_key => 'openscap_proxy_id', :class_name => "::Host"
8
+ has_many :arf_reports, :foreign_key => 'openscap_proxy_id', :class_name => "ForemanOpenscap::ArfReport"
9
+ PORT_MATCH = /:(\d+)\z/
10
+ after_destroy :delete_associated_arf_reports
11
+ end
12
+
13
+ def port
14
+ url.match(PORT_MATCH)[1]
15
+ end
16
+
17
+ private
18
+
19
+ def delete_associated_arf_reports
20
+ ForemanOpenscap::ArfReport.where(:openscap_proxy_id => id).delete_all
21
+ end
22
+ end
23
+ end
@@ -3,7 +3,9 @@ require 'foreman_openscap/helper'
3
3
  module ForemanOpenscap
4
4
  class ArfReport < ::Report
5
5
  include Taxonomix
6
+ include OpenscapProxyExtensions
6
7
 
8
+ # attr_accessible :host_id, :reported_at, :status, :metrics
7
9
  RESULT = %w(pass fail error unknown notapplicable notchecked notselected informational fixed)
8
10
  METRIC = %w(passed othered failed)
9
11
  BIT_NUM = 10
@@ -11,15 +13,15 @@ module ForemanOpenscap
11
13
 
12
14
  has_one :policy_arf_report, :dependent => :destroy
13
15
  has_one :policy, :through => :policy_arf_report
14
- has_one :asset, :through => :host, :class_name => 'ForemanOpenscap::Asset'
16
+ has_one :asset, :through => :host, :class_name => 'ForemanOpenscap::Asset', :as => :assetable
15
17
  after_save :assign_locations_organizations
16
18
  validate :result, :inclusion => { :in => RESULT }
17
19
 
18
- default_scope {
20
+ default_scope do
19
21
  with_taxonomy_scope do
20
22
  order("#{self.table_name}.created_at DESC")
21
23
  end
22
- }
24
+ end
23
25
 
24
26
  scope :hosts, lambda { includes(:policy) }
25
27
  scope :of_policy, lambda { |policy_id| joins(:policy_arf_report).merge(PolicyArfReport.of_policy(policy_id)) }
@@ -40,13 +42,13 @@ module ForemanOpenscap
40
42
  ON reports.id = latest.id")
41
43
  }
42
44
 
43
- scope :failed, lambda { where("(#{report_status_column} >> #{ bit_mask 'failed' }) > 0") }
44
- scope :not_failed, lambda { where("(#{report_status_column} >> #{ bit_mask 'failed' }) = 0") }
45
+ scope :failed, lambda { where("(#{report_status_column} >> #{bit_mask 'failed'}) > 0") }
46
+ scope :not_failed, lambda { where("(#{report_status_column} >> #{bit_mask 'failed'}) = 0") }
45
47
 
46
- scope :othered, lambda { where("(#{report_status_column} >> #{ bit_mask 'othered' }) > 0").merge(not_failed) }
47
- scope :not_othered, lambda { where("(#{report_status_column} >> #{ bit_mask 'othered' }) = 0") }
48
+ scope :othered, lambda { where("(#{report_status_column} >> #{bit_mask 'othered'}) > 0").merge(not_failed) }
49
+ scope :not_othered, lambda { where("(#{report_status_column} >> #{bit_mask 'othered'}) = 0") }
48
50
 
49
- scope :passed, lambda { where("(#{report_status_column} >> #{ bit_mask 'passed' }) > 0").merge(not_failed).merge(not_othered) }
51
+ scope :passed, lambda { where("(#{report_status_column} >> #{bit_mask 'passed'}) > 0").merge(not_failed).merge(not_othered) }
50
52
 
51
53
  def self.bit_mask(status)
52
54
  ComplianceStatus.bit_mask(status)
@@ -97,21 +99,25 @@ module ForemanOpenscap
97
99
  policy = Policy.find(params[:policy_id])
98
100
  ArfReport.transaction do
99
101
  # TODO:RAILS-4.0: This should become arf_report = ArfReport.find_or_create_by! ...
100
- arf_report = ArfReport.create!(:host_id => asset.host.id,
102
+ arf_report = ArfReport.create!(:host => asset.host,
101
103
  :reported_at => Time.at(params[:date].to_i),
102
104
  :status => params[:metrics],
103
- :metrics => params[:metrics])
105
+ :metrics => params[:metrics],
106
+ :openscap_proxy => asset.host.openscap_proxy)
104
107
  PolicyArfReport.where(:arf_report_id => arf_report.id, :policy_id => policy.id, :digest => params[:digest]).first_or_create!
105
108
  if params[:logs]
106
109
  params[:logs].each do |log|
107
110
  src = Source.find_or_create(log[:source])
108
- msg = Message.find_or_create(N_(log[:title]))
111
+ digest = Digest::SHA1.hexdigest(log[:title])
112
+ msg = Message.where(:value => N_(log[:title]), :digest => digest, :severity => log[:severity],
113
+ :description => newline_to_space(log[:description]), :rationale => newline_to_space(log[:rationale]),
114
+ :scap_references => references_links(log[:references])).first_or_create
109
115
  #TODO: log level
110
116
  Log.create!(:source_id => src.id,
111
117
  :message_id => msg.id,
112
- :level_id => 1,
118
+ :level => :info,
113
119
  :result => log[:result],
114
- :report_id => arf_report.id)
120
+ :report => arf_report)
115
121
  end
116
122
  end
117
123
  end
@@ -138,11 +144,11 @@ module ForemanOpenscap
138
144
  end
139
145
 
140
146
  def to_html
141
- proxy.arf_report_html(self, ForemanOpenscap::Helper::find_name_or_uuid_by_host(host))
147
+ openscap_proxy_api.arf_report_html(self, ForemanOpenscap::Helper::find_name_or_uuid_by_host(host))
142
148
  end
143
149
 
144
150
  def to_bzip
145
- proxy.arf_report_bzip(self, ForemanOpenscap::Helper::find_name_or_uuid_by_host(host))
151
+ openscap_proxy_api.arf_report_bzip(self, ForemanOpenscap::Helper::find_name_or_uuid_by_host(host))
146
152
  end
147
153
 
148
154
  def equal?(other)
@@ -154,12 +160,27 @@ module ForemanOpenscap
154
160
  policy.id == other.policy.id
155
161
  end
156
162
 
157
- def proxy
158
- return @proxy if @proxy
159
- scap_class = host.info['classes']['foreman_scap_client']
160
- port = scap_class['port']
161
- server = scap_class['server']
162
- @proxy = ::ProxyAPI::Openscap.new(:url => "https://#{server}:#{port}")
163
+ def destroy
164
+ if openscap_proxy_api.destroy_report(self, ForemanOpenscap::Helper::find_name_or_uuid_by_host(host))
165
+ super
166
+ else
167
+ false
168
+ end
169
+ end
170
+
171
+ def self.newline_to_space(string)
172
+ string.gsub(/ *\n+/, " ")
173
+ end
174
+
175
+ def self.references_links(references)
176
+ return if references.nil?
177
+ html_links = []
178
+ references.each do |reference|
179
+ next if reference['title'] == 'test_attestation' # A blank url created by OpenSCAP
180
+ reference['html_link'] = "<a href='#{reference['href']}'>#{reference['href']}</a>" if reference['title'].blank?
181
+ html_links << reference['html_link']
182
+ end
183
+ html_links.join(', ')
163
184
  end
164
185
  end
165
186
  end
@@ -21,9 +21,9 @@ module ForemanOpenscap
21
21
  SERVER_CLASS_PARAMETER = 'server'
22
22
  PORT_CLASS_PARAMETER = 'port'
23
23
 
24
- validates :name, :presence => true, :uniqueness => true, :format => {without: /\s/}
24
+ validates :name, :presence => true, :uniqueness => true, :format => { :without => /\s/ }
25
25
  validate :ensure_needed_puppetclasses
26
- validates :period, :inclusion => {:in => %w[weekly monthly custom]},
26
+ validates :period, :inclusion => {:in => %w(weekly monthly custom)},
27
27
  :if => Proc.new { |policy| policy.new_record? ? policy.step_index > 3 : !policy.id.blank? }
28
28
  validates :weekday, :inclusion => {:in => Date::DAYNAMES.map(&:downcase)},
29
29
  :if => Proc.new { |policy| policy.period == 'weekly' && (policy.new_record? ? policy.step_index > 3 : !policy.id.blank?) }
@@ -36,11 +36,11 @@ module ForemanOpenscap
36
36
  after_save :assign_policy_to_hostgroups
37
37
  # before_destroy - ensure that the policy has no hostgroups, or classes
38
38
 
39
- default_scope {
39
+ default_scope do
40
40
  with_taxonomy_scope do
41
41
  order("foreman_openscap_policies.name")
42
42
  end
43
- }
43
+ end
44
44
 
45
45
  def assign_assets(a)
46
46
  self.asset_ids = (self.asset_ids + a.collect(&:id)).uniq
@@ -138,14 +138,14 @@ module ForemanOpenscap
138
138
 
139
139
  def used_location_ids
140
140
  Location.joins(:taxable_taxonomies).where(
141
- 'taxable_taxonomies.taxable_type' => 'ForemanOpenscap::Policy',
142
- 'taxable_taxonomies.taxable_id' => id).pluck("#{Location.arel_table.name}.id")
141
+ 'taxable_taxonomies.taxable_type' => 'ForemanOpenscap::Policy',
142
+ 'taxable_taxonomies.taxable_id' => id).pluck("#{Location.arel_table.name}.id")
143
143
  end
144
144
 
145
145
  def used_organization_ids
146
146
  Organization.joins(:taxable_taxonomies).where(
147
- 'taxable_taxonomies.taxable_type' => 'ForemanOpenscap::Policy',
148
- 'taxable_taxonomies.taxable_id' => id).pluck("#{Location.arel_table.name}.id")
147
+ 'taxable_taxonomies.taxable_type' => 'ForemanOpenscap::Policy',
148
+ 'taxable_taxonomies.taxable_id' => id).pluck("#{Location.arel_table.name}.id")
149
149
  end
150
150
 
151
151
  def used_hostgroup_ids
@@ -163,10 +163,10 @@ module ForemanOpenscap
163
163
 
164
164
  def to_enc
165
165
  {
166
- 'id' => self.id,
167
- 'profile_id' => self.scap_content_profile.try(:profile_id) || '',
168
- 'content_path' => "/var/lib/openscap/content/#{self.scap_content.digest}.xml",
169
- 'download_path' => "/compliance/policies/#{self.id}/content" # default to proxy path
166
+ 'id' => self.id,
167
+ 'profile_id' => self.scap_content_profile.try(:profile_id) || '',
168
+ 'content_path' => "/var/lib/openscap/content/#{self.scap_content.digest}.xml",
169
+ 'download_path' => "/compliance/policies/#{self.id}/content" # default to proxy path
170
170
  }.merge(period_enc)
171
171
  end
172
172
 
@@ -175,22 +175,22 @@ module ForemanOpenscap
175
175
  def period_enc
176
176
  # get crontab expression as an array (minute hour day_of_month month day_of_week)
177
177
  cron_parts = case period
178
- when 'weekly'
179
- ['0', '1', '*', '*', weekday_number.to_s]
180
- when 'monthly'
181
- ['0', '1', day_of_month.to_s, '*', '*']
182
- when 'custom'
183
- cron_line_split
184
- else
185
- raise 'invalid period specification'
178
+ when 'weekly'
179
+ ['0', '1', '*', '*', weekday_number.to_s]
180
+ when 'monthly'
181
+ ['0', '1', day_of_month.to_s, '*', '*']
182
+ when 'custom'
183
+ cron_line_split
184
+ else
185
+ fail 'invalid period specification'
186
186
  end
187
187
 
188
188
  {
189
- 'minute' => cron_parts[0],
190
- 'hour' => cron_parts[1],
191
- 'monthday' => cron_parts[2],
192
- 'month' => cron_parts[3],
193
- 'weekday' => cron_parts[4],
189
+ 'minute' => cron_parts[0],
190
+ 'hour' => cron_parts[1],
191
+ 'monthday' => cron_parts[2],
192
+ 'month' => cron_parts[3],
193
+ 'weekday' => cron_parts[4],
194
194
  }
195
195
  end
196
196
 
@@ -205,7 +205,7 @@ module ForemanOpenscap
205
205
  return false
206
206
  end
207
207
 
208
- unless policies_param = puppetclass.class_params.where(:key => POLICIES_CLASS_PARAMETER).first
208
+ unless policies_param = puppetclass.class_params.find_by_key(POLICIES_CLASS_PARAMETER)
209
209
  errors[:base] << _("Puppet class %{class} does not have %{parameter} class parameter.") % {:class => SCAP_PUPPET_CLASS, :parameter => POLICIES_CLASS_PARAMETER}
210
210
  return false
211
211
  end
@@ -257,18 +257,18 @@ module ForemanOpenscap
257
257
  end
258
258
 
259
259
  def populate_overrides(puppetclass, hostgroup)
260
- puppetclass.class_params.where(:override => true).each do |override|
261
- if hostgroup.puppet_proxy && (url = hostgroup.puppet_proxy.url).present?
262
- case override.key
263
- when SERVER_CLASS_PARAMETER
264
- lookup_value = LookupValue.where(:match => "hostgroup=#{hostgroup.to_label}", :lookup_key_id => override.id).first_or_initialize
265
- puppet_proxy_fqdn = URI.parse(url).host
266
- lookup_value.update_attribute(:value, puppet_proxy_fqdn)
267
- when PORT_CLASS_PARAMETER
268
- lookup_value = LookupValue.where(:match => "hostgroup=#{hostgroup.to_label}", :lookup_key_id => override.id).first_or_initialize
269
- puppet_proxy_port = URI.parse(url).port
270
- lookup_value.update_attribute(:value, puppet_proxy_port)
271
- end
260
+ puppetclass.class_params.where(:override => true).find_each do |override|
261
+ next unless hostgroup.puppet_proxy && (url = hostgroup.puppet_proxy.url).present?
262
+
263
+ case override.key
264
+ when SERVER_CLASS_PARAMETER
265
+ lookup_value = LookupValue.where(:match => "hostgroup=#{hostgroup.to_label}", :lookup_key_id => override.id).first_or_initialize
266
+ puppet_proxy_fqdn = URI.parse(url).host
267
+ lookup_value.update_attribute(:value, puppet_proxy_fqdn)
268
+ when PORT_CLASS_PARAMETER
269
+ lookup_value = LookupValue.where(:match => "hostgroup=#{hostgroup.to_label}", :lookup_key_id => override.id).first_or_initialize
270
+ puppet_proxy_port = URI.parse(url).port
271
+ lookup_value.update_attribute(:value, puppet_proxy_port)
272
272
  end
273
273
  end
274
274
  end