foreman_openscap 0.5.4 → 0.6.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 (75) hide show
  1. checksums.yaml +7 -7
  2. data/README.md +14 -0
  3. data/app/assets/javascripts/foreman_openscap/policy_edit.js +1 -1
  4. data/app/controllers/api/v2/compliance/policies_controller.rb +12 -9
  5. data/app/controllers/api/v2/compliance/scap_contents_controller.rb +4 -2
  6. data/app/controllers/concerns/foreman/controller/parameters/policy.rb +12 -0
  7. data/app/controllers/concerns/foreman/controller/parameters/policy_api.rb +21 -0
  8. data/app/controllers/concerns/foreman/controller/parameters/scap_content.rb +15 -0
  9. data/app/controllers/policies_controller.rb +7 -3
  10. data/app/controllers/scap_contents_controller.rb +4 -2
  11. data/app/helpers/{dashboard_helper.rb → compliance_dashboard_helper.rb} +2 -2
  12. data/app/helpers/policy_dashboard_helper.rb +9 -4
  13. data/app/models/concerns/foreman_openscap/host_extensions.rb +3 -5
  14. data/app/models/concerns/foreman_openscap/hostgroup_extensions.rb +1 -1
  15. data/app/models/concerns/foreman_openscap/log_extensions.rb +0 -1
  16. data/app/models/concerns/foreman_openscap/openscap_proxy_core_extensions.rb +1 -1
  17. data/app/models/concerns/foreman_openscap/openscap_proxy_extensions.rb +1 -2
  18. data/app/models/foreman_openscap/arf_report.rb +6 -4
  19. data/app/models/foreman_openscap/compliance_status.rb +3 -1
  20. data/app/models/foreman_openscap/policy.rb +62 -33
  21. data/app/models/foreman_openscap/scap_content.rb +1 -3
  22. data/app/views/arf_reports/_list.html.erb +1 -1
  23. data/app/views/arf_reports/show.html.erb +4 -4
  24. data/app/views/compliance_hosts/show.html.erb +1 -1
  25. data/app/views/dashboard/_compliance_host_reports_widget.html.erb +6 -6
  26. data/app/views/policies/index.html.erb +2 -2
  27. data/app/views/policies/steps/_schedule_form.html.erb +1 -1
  28. data/app/views/policies/steps/_step_form.html.erb +1 -0
  29. data/app/views/policies/welcome.html.erb +1 -1
  30. data/app/views/policy_dashboard/index.html.erb +2 -2
  31. data/app/views/scap_contents/index.html.erb +2 -2
  32. data/app/views/scap_contents/welcome.html.erb +1 -1
  33. data/db/migrate/20160830113437_remove_deleted_policy.rb +10 -0
  34. data/db/seeds.d/openscap_policy_notification.rb +2 -0
  35. data/lib/foreman_openscap/data_migration.rb +1 -1
  36. data/lib/foreman_openscap/engine.rb +11 -1
  37. data/lib/foreman_openscap/helper.rb +4 -8
  38. data/lib/foreman_openscap/version.rb +1 -1
  39. data/locale/Makefile +60 -0
  40. data/locale/de/LC_MESSAGES/foreman_openscap.mo +0 -0
  41. data/locale/de/foreman_openscap.po +616 -0
  42. data/locale/en_GB/LC_MESSAGES/foreman_openscap.mo +0 -0
  43. data/locale/en_GB/foreman_openscap.po +616 -0
  44. data/locale/es/LC_MESSAGES/foreman_openscap.mo +0 -0
  45. data/locale/es/foreman_openscap.po +616 -0
  46. data/locale/foreman_openscap.pot +873 -0
  47. data/locale/fr/LC_MESSAGES/foreman_openscap.mo +0 -0
  48. data/locale/fr/foreman_openscap.po +616 -0
  49. data/locale/gl/LC_MESSAGES/foreman_openscap.mo +0 -0
  50. data/locale/gl/foreman_openscap.po +616 -0
  51. data/locale/it/LC_MESSAGES/foreman_openscap.mo +0 -0
  52. data/locale/it/foreman_openscap.po +616 -0
  53. data/locale/ja/LC_MESSAGES/foreman_openscap.mo +0 -0
  54. data/locale/ja/foreman_openscap.po +616 -0
  55. data/locale/ko/LC_MESSAGES/foreman_openscap.mo +0 -0
  56. data/locale/ko/foreman_openscap.po +616 -0
  57. data/locale/pt_BR/LC_MESSAGES/foreman_openscap.mo +0 -0
  58. data/locale/pt_BR/foreman_openscap.po +616 -0
  59. data/locale/ru/LC_MESSAGES/foreman_openscap.mo +0 -0
  60. data/locale/ru/foreman_openscap.po +617 -0
  61. data/locale/sv_SE/LC_MESSAGES/foreman_openscap.mo +0 -0
  62. data/locale/sv_SE/foreman_openscap.po +616 -0
  63. data/locale/zanata.xml +29 -0
  64. data/locale/zh_CN/LC_MESSAGES/foreman_openscap.mo +0 -0
  65. data/locale/zh_CN/foreman_openscap.po +616 -0
  66. data/locale/zh_TW/LC_MESSAGES/foreman_openscap.mo +0 -0
  67. data/locale/zh_TW/foreman_openscap.po +616 -0
  68. data/test/factories/policy_factory.rb +2 -2
  69. data/test/functional/api/v2/compliance/policies_controller_test.rb +7 -3
  70. data/test/test_plugin_helper.rb +35 -37
  71. data/test/unit/concerns/openscap_proxy_extenstions_test.rb +21 -0
  72. data/test/unit/openscap_host_test.rb +3 -1
  73. data/test/unit/policy_test.rb +125 -0
  74. data/test/unit/scap_content_test.rb +5 -0
  75. metadata +231 -198
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 96a6e2184a76a03fd739e6c59c6e84f6cb5085fa
4
- data.tar.gz: 3d60a8e2769d5f1f965776ae1dc574905c2fb06a
5
- SHA512:
6
- metadata.gz: a182595dc0be182b440010db2c6ae0ddbc6bf2ade6224cdaf7d9df6f7a1cc04fa4dca4f1d93f99ffdecd39ea7a0bf68eb872af7cbf61c626f2479806c54bd748
7
- data.tar.gz: b893e5bddaa8888d8fa602520dec17b3c8e1d97f5b060dfb3a85efce17d32733d4f6929c8a6782c3e5d92d25cf36bd4af93f92705291de3f2228f9902eb2925e
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 851cba0254a778b37d861c8801c59e5922dfa240
4
+ data.tar.gz: 5c197e57e737aa99d9eee649016a777da56be9b3
5
+ SHA512:
6
+ metadata.gz: 0060d5c3f69d2750ee68847295ca415fc3815ca881ba3a2c695213d1d944fc75743adced9ac8a761bd160e27f445aba5101d9b3611fb89a6ddd2df570b45244e
7
+ data.tar.gz: 461c91f862ce0076d6287b7b962c9ce2597b6d59ff59ffcebc8bbcd323ab8ee8a2d5bb7c4a6a52f98426e29b5e2016da7c038f6de48ea16ac4f812187d745233
data/README.md CHANGED
@@ -141,6 +141,20 @@ Make sure that
141
141
  # service foreman restart
142
142
  ```
143
143
 
144
+ ## Releasing
145
+
146
+ follow these steps:
147
+
148
+ 1. Bump the version.rb to desired number
149
+ 2. git commit -a -m "Version $number"
150
+ 3. rake release
151
+
152
+ the commit gets tagged with what it find in version.rb
153
+
154
+ if you have commit permissions, the commit and the tag gets pushed to origin remote
155
+
156
+ if you're the gem owner, gem is built and uploaded to rubygems.org
157
+
144
158
  ## Copyright
145
159
 
146
160
  Copyright (c) 2014--2015 Red Hat, Inc.
@@ -1,7 +1,7 @@
1
1
  function scap_content_selected(element){
2
2
  var attrs = attribute_hash(['scap_content_id']);
3
3
  var url = $(element).attr('data-url');
4
- foreman.tools.showSpinner();
4
+ tfm.tools.showSpinner();
5
5
  $.ajax({
6
6
  data: attrs,
7
7
  type: 'post',
@@ -2,6 +2,7 @@ module Api::V2
2
2
  module Compliance
3
3
  class PoliciesController < ::Api::V2::BaseController
4
4
  include Foreman::Controller::SmartProxyAuth
5
+ include Foreman::Controller::Parameters::PolicyApi
5
6
 
6
7
  add_smart_proxy_filters :content, :features => 'Openscap'
7
8
 
@@ -21,14 +22,14 @@ module Api::V2
21
22
  api_compliance_policy_url(@policy)
22
23
  end
23
24
 
24
- api :GET, '/compliance/policies', N_('List SCAP contents')
25
+ api :GET, '/compliance/policies', N_('List Policies')
25
26
  param_group :search_and_pagination, ::Api::V2::BaseController
26
27
 
27
28
  def index
28
29
  @policies = resource_scope_for_index(:permission => :edit_compliance)
29
30
  end
30
31
 
31
- api :GET, '/compliance/policies/:id', N_('Show an SCAP content')
32
+ api :GET, '/compliance/policies/:id', N_('Show a Policy')
32
33
  param :id, :identifier, :required => true
33
34
 
34
35
  def show
@@ -40,30 +41,32 @@ module Api::V2
40
41
  param :description, String, :desc => N_('Policy description')
41
42
  param :scap_content_id, Integer, :required => true, :desc => N_('Policy SCAP content ID')
42
43
  param :scap_content_profile_id, Integer, :required => true, :desc => N_('Policy SCAP content profile ID')
43
- param :period, String, :required => true, :desc => N_('Policy schedule period')
44
- param :weekday, String, :required => true, :desc => N_('Policy schedule weekday')
44
+ param :period, String, :desc => N_('Policy schedule period (weekly, monthly, custom)')
45
+ param :weekday, String, :desc => N_('Policy schedule weekday (only if period == "weekly")')
46
+ param :day_of_month, Integer, :desc => N_('Policy schedule day of month (only if period == "monthly")')
47
+ param :cron_line, String, :desc => N_('Policy schedule cron line (only if period == "custom")')
45
48
  param :hostgroup_ids, Array, :desc => N_('Apply policy to host groups')
46
49
  param_group :taxonomies, ::Api::V2::BaseController
47
50
  end
48
51
  end
49
52
 
50
- api :POST, '/compliance/policies', N_('Create a policy')
53
+ api :POST, '/compliance/policies', N_('Create a Policy')
51
54
  param_group :policy, :as => :create
52
55
 
53
56
  def create
54
- @policy = ForemanOpenscap::Policy.new(params[:policy])
57
+ @policy = ForemanOpenscap::Policy.new(policy_params)
55
58
  process_response @policy.save
56
59
  end
57
60
 
58
- api :PUT, '/compliance/policies/:id', N_('Update a policy')
61
+ api :PUT, '/compliance/policies/:id', N_('Update a Policy')
59
62
  param :id, :identifier, :required => true
60
63
  param_group :policy
61
64
 
62
65
  def update
63
- process_response @policy.update_attributes(params[:policy])
66
+ process_response @policy.update_attributes(policy_params)
64
67
  end
65
68
 
66
- api :DELETE, '/compliance/policies/:id', N_('Deletes a policy')
69
+ api :DELETE, '/compliance/policies/:id', N_('Delete a Policy')
67
70
  param :id, :identifier, :required => true
68
71
 
69
72
  def destroy
@@ -1,6 +1,7 @@
1
1
  module Api::V2
2
2
  module Compliance
3
3
  class ScapContentsController < ::Api::V2::BaseController
4
+ include Foreman::Controller::Parameters::ScapContent
4
5
  before_filter :find_resource, :except => %w(index create)
5
6
 
6
7
  def resource_name
@@ -36,6 +37,7 @@ module Api::V2
36
37
  param :scap_content, Hash, :required => true, :action_aware => true do
37
38
  param :title, String, :required => true, :desc => N_('SCAP content name')
38
39
  param :scap_file, String, :required => true, :desc => N_('XML containing SCAP content')
40
+ param :original_filename, String, :desc => N_('Original file name of the XML file')
39
41
  param_group :taxonomies, ::Api::V2::BaseController
40
42
  end
41
43
  end
@@ -44,7 +46,7 @@ module Api::V2
44
46
  param_group :scap_content, :as => :create
45
47
 
46
48
  def create
47
- @scap_content = ForemanOpenscap::ScapContent.new(params[:scap_content])
49
+ @scap_content = ForemanOpenscap::ScapContent.new(scap_content_params)
48
50
  process_response @scap_content.save
49
51
  end
50
52
 
@@ -53,7 +55,7 @@ module Api::V2
53
55
  param_group :scap_content
54
56
 
55
57
  def update
56
- process_response @scap_content.update_attributes(params[:scap_content])
58
+ process_response @scap_content.update_attributes(scap_content_params)
57
59
  end
58
60
 
59
61
  api :DELETE, '/compliance/scap_contents/:id', N_('Deletes an SCAP content')
@@ -0,0 +1,12 @@
1
+ module Foreman::Controller::Parameters::Policy
2
+ extend ActiveSupport::Concern
3
+ include PolicyApi
4
+
5
+ class_methods do
6
+ def policy_params_filter
7
+ Foreman::ParameterFilter.new(::ForemanOpenscap::Policy).tap do |filter|
8
+ filter.permit([:current_step, :wizard_initiated] + filter_params_list)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,21 @@
1
+ module Foreman::Controller::Parameters::PolicyApi
2
+ extend ActiveSupport::Concern
3
+
4
+ class_methods do
5
+ def filter_params_list
6
+ [:description, :name, :period, :scap_content_id, :scap_content_profile_id,
7
+ :weekday, :day_of_month, :cron_line, :location_ids => [], :organization_ids => [],
8
+ :hostgroup_ids => []]
9
+ end
10
+
11
+ def policy_params_filter
12
+ Foreman::ParameterFilter.new(::ForemanOpenscap::Policy).tap do |filter|
13
+ filter.permit filter_params_list
14
+ end
15
+ end
16
+ end
17
+
18
+ def policy_params
19
+ self.class.policy_params_filter.filter_params(params, parameter_filter_context)
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ module Foreman::Controller::Parameters::ScapContent
2
+ extend ActiveSupport::Concern
3
+
4
+ class_methods do
5
+ def scap_content_params_filter
6
+ Foreman::ParameterFilter.new(::ForemanOpenscap::ScapContent).tap do |filter|
7
+ filter.permit :original_filename, :scap_file, :title, :location_ids => [], :organization_ids => []
8
+ end
9
+ end
10
+ end
11
+
12
+ def scap_content_params
13
+ self.class.scap_content_params_filter.filter_params(params, parameter_filter_context)
14
+ end
15
+ end
@@ -1,5 +1,7 @@
1
1
  class PoliciesController < ApplicationController
2
2
  include Foreman::Controller::AutoCompleteSearch
3
+ include Foreman::Controller::Parameters::Policy
4
+
3
5
  before_filter :find_by_id, :only => [:show, :edit, :update, :parse, :destroy]
4
6
  before_filter :find_multiple, :only => [:select_multiple_hosts, :update_multiple_hosts, :disassociate_multiple_hosts, :remove_policy_from_multiple_hosts]
5
7
 
@@ -18,7 +20,7 @@ class PoliciesController < ApplicationController
18
20
  end
19
21
 
20
22
  def new
21
- @policy = ::ForemanOpenscap::Policy.new
23
+ @policy = ::ForemanOpenscap::Policy.new(:wizard_initiated => true)
22
24
  end
23
25
 
24
26
  def show
@@ -29,7 +31,9 @@ class PoliciesController < ApplicationController
29
31
  end
30
32
 
31
33
  def create
32
- @policy = ::ForemanOpenscap::Policy.new(params[:policy])
34
+ # we must call unscoped, otherwise taxonomix default scope gets mixed into taxable_taxonomies object
35
+ # setting taxable_id, making them invalid
36
+ @policy = ::ForemanOpenscap::Policy.unscoped.new(policy_params)
33
37
  if @policy.wizard_completed? && @policy.save
34
38
  process_success :success_redirect => policies_path
35
39
  else
@@ -46,7 +50,7 @@ class PoliciesController < ApplicationController
46
50
  end
47
51
 
48
52
  def update
49
- if @policy.update_attributes(params[:policy])
53
+ if @policy.update_attributes(policy_params)
50
54
  process_success :success_redirect => policies_path
51
55
  else
52
56
  process_error :object => @policy
@@ -1,5 +1,7 @@
1
1
  class ScapContentsController < ApplicationController
2
2
  include Foreman::Controller::AutoCompleteSearch
3
+ include Foreman::Controller::Parameters::ScapContent
4
+
3
5
  before_filter :handle_file_upload, :only => [:create, :update]
4
6
  before_filter :find_by_id, :only => [:show, :edit, :update, :destroy]
5
7
 
@@ -22,7 +24,7 @@ class ScapContentsController < ApplicationController
22
24
  end
23
25
 
24
26
  def create
25
- @scap_content = ForemanOpenscap::ScapContent.new(params[:scap_content])
27
+ @scap_content = ForemanOpenscap::ScapContent.new(scap_content_params)
26
28
  if @scap_content.save
27
29
  process_success
28
30
  else
@@ -31,7 +33,7 @@ class ScapContentsController < ApplicationController
31
33
  end
32
34
 
33
35
  def update
34
- if @scap_content.update_attributes(params[:scap_content])
36
+ if @scap_content.update_attributes(scap_content_params)
35
37
  process_success
36
38
  else
37
39
  process_error
@@ -8,9 +8,9 @@
8
8
  # along with this software; if not, see http://www.gnu.org/licenses/gpl.txt
9
9
  #
10
10
 
11
- module DashboardHelper
11
+ module ComplianceDashboardHelper
12
12
 
13
- def latest_headers
13
+ def latest_compliance_headers
14
14
  string = "<th>#{_("Host")}</th>"
15
15
  string += "<th>#{_("Policy")}</th>"
16
16
  # TRANSLATORS: initial character of Passed
@@ -16,10 +16,6 @@ module PolicyDashboardHelper
16
16
  :report_missing => '#92A8CD',
17
17
  }
18
18
 
19
- def policy_widget_list
20
- ForemanOpenscap::PolicyDashboard::Manager.widgets
21
- end
22
-
23
19
  def host_breakdown_chart(report, options = {})
24
20
  data = []
25
21
  [[:compliant_hosts, _('Compliant hosts')],
@@ -40,4 +36,13 @@ module PolicyDashboardHelper
40
36
  content_tag(:h4, @report[label])
41
37
  end
42
38
  end
39
+
40
+ def compliance_widget(opts)
41
+ name = opts.delete(:name)
42
+ template = opts.delete(:template)
43
+ widget = Widget.new(opts)
44
+ widget.name = name
45
+ widget.template = template
46
+ widget
47
+ end
43
48
  end
@@ -46,13 +46,11 @@ module ForemanOpenscap
46
46
  AND foreman_openscap_asset_policies.policy_id = '#{policy.id}')")
47
47
  }
48
48
 
49
- alias_method_chain :set_hostgroup_defaults, :openscap
49
+ alias_method_chain :inherited_attributes, :openscap
50
50
  end
51
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)
52
+ def inherited_attributes_with_openscap
53
+ inherited_attributes_without_openscap.concat(%w(openscap_proxy_id))
56
54
  end
57
55
 
58
56
  def policies=(policies)
@@ -3,7 +3,7 @@ module ForemanOpenscap
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
- has_one :asset, :as => :assetable, :class_name => "::ForemanOpenscap::Asset"
6
+ has_one :asset, :as => :assetable, :class_name => "::ForemanOpenscap::Asset", dependent: :destroy
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
@@ -2,7 +2,6 @@ module ForemanOpenscap
2
2
  module LogExtensions
3
3
  extend ActiveSupport::Concern
4
4
  included do
5
- attr_accessible :result
6
5
  SCAP_RESULT = %w(pass fail error unknown notapplicable notchecked notselected informational fixed)
7
6
  validate :scap_result
8
7
  end
@@ -9,7 +9,7 @@ module ForemanOpenscap
9
9
  end
10
10
 
11
11
  def update_scap_client
12
- update_scap_client_params if openscap_proxy_id_changed?
12
+ update_scap_client_params if changed.include?('openscap_proxy_id')
13
13
  end
14
14
 
15
15
  def update_scap_client_params
@@ -4,13 +4,12 @@ module ForemanOpenscap
4
4
 
5
5
  included do
6
6
  belongs_to :openscap_proxy, :class_name => "SmartProxy"
7
- attr_accessible :openscap_proxy_id, :openscap_proxy
8
7
  end
9
8
 
10
9
  def openscap_proxy_api
11
10
  return @openscap_api if @openscap_api
12
11
  proxy_url = openscap_proxy.url if openscap_proxy
13
- fail(_("No OpenSCAP proxy found for %s") % id) unless proxy_url
12
+ raise ::Foreman::Exception.new(N_("No OpenSCAP proxy found for %{class} with %{id}"), { :class => self.class, :id => id }) unless proxy_url
14
13
  @openscap_api = ::ProxyAPI::Openscap.new(:url => proxy_url)
15
14
  end
16
15
  end
@@ -164,11 +164,13 @@ module ForemanOpenscap
164
164
  end
165
165
 
166
166
  def destroy
167
- if openscap_proxy_api.destroy_report(self, ForemanOpenscap::Helper::find_name_or_uuid_by_host(host))
168
- super
169
- else
170
- false
167
+ begin
168
+ openscap_proxy_api.destroy_report(self, ForemanOpenscap::Helper::find_name_or_uuid_by_host(host))
169
+ rescue Foreman::Exception => e
170
+ logger.error "Failed to delete report with id #{id} from proxy, cause: #{e.message}"
171
+ logger.debug e.backtrace.join("\n\t")
171
172
  end
173
+ super
172
174
  end
173
175
 
174
176
  def self.newline_to_space(string)
@@ -36,7 +36,9 @@ module ForemanOpenscap
36
36
  end
37
37
  end
38
38
 
39
- def relevant?
39
+ def relevant?(options = {})
40
+ # May fail host status during migration
41
+ return false unless ForemanOpenscap::Asset.table_exists?
40
42
  host.policies.present?
41
43
  end
42
44
 
@@ -2,17 +2,14 @@ module ForemanOpenscap
2
2
  class Policy < ActiveRecord::Base
3
3
  include Authorizable
4
4
  include Taxonomix
5
- attr_accessible :description, :name, :period, :scap_content_id, :scap_content_profile_id,
6
- :weekday, :day_of_month, :cron_line, :location_ids, :organization_ids,
7
- :current_step, :hostgroup_ids
8
- attr_writer :current_step
5
+ attr_writer :current_step, :wizard_initiated
9
6
 
10
7
  belongs_to :scap_content
11
8
  belongs_to :scap_content_profile
12
9
  has_many :policy_arf_reports
13
10
  has_many :arf_reports, :through => :policy_arf_reports, :dependent => :destroy
14
11
  has_many :asset_policies
15
- has_many :assets, :through => :asset_policies
12
+ has_many :assets, :through => :asset_policies, :as => :assetable, :dependent => :destroy
16
13
 
17
14
  scoped_search :on => :name, :complete_value => true
18
15
 
@@ -21,17 +18,15 @@ module ForemanOpenscap
21
18
  SERVER_CLASS_PARAMETER = 'server'
22
19
  PORT_CLASS_PARAMETER = 'port'
23
20
 
24
- validates :name, :presence => true, :uniqueness => true, :format => { :without => /\s/ }
21
+ before_validation :update_period_attrs
22
+
23
+ validates :name, :presence => true, :uniqueness => true
25
24
  validate :ensure_needed_puppetclasses
26
- validates :period, :inclusion => {:in => %w(weekly monthly custom)},
27
- :if => Proc.new { |policy| policy.new_record? ? policy.step_index > 3 : !policy.id.blank? }
28
- validates :weekday, :inclusion => {:in => Date::DAYNAMES.map(&:downcase)},
29
- :if => Proc.new { |policy| policy.period == 'weekly' && (policy.new_record? ? policy.step_index > 3 : !policy.id.blank?) }
30
- validates :day_of_month, :numericality => {:greater_than => 0, :less_than => 32},
31
- :if => Proc.new { |policy| policy.period == 'monthly'&& (policy.new_record? ? policy.step_index > 3 : !policy.id.blank?) }
32
- validate :valid_cron_line
33
- validate :ensure_period_specification_present
25
+ validates :period, :inclusion => {:in => %w(weekly monthly custom), :message => _('is not a valid value')},
26
+ :if => Proc.new { |policy| policy.should_validate?('Schedule') }
27
+
34
28
 
29
+ validate :valid_cron_line, :valid_weekday, :valid_day_of_month
35
30
 
36
31
  after_save :assign_policy_to_hostgroups
37
32
  # before_destroy - ensure that the policy has no hostgroups, or classes
@@ -67,10 +62,11 @@ module ForemanOpenscap
67
62
 
68
63
  def hostgroup_ids=(ids)
69
64
  hostgroup_assets = []
70
- ids.reject(&:empty?).map do |id|
71
- hostgroup_assets << assets.where(:assetable_type => 'Hostgroup', :assetable_id => id).first_or_create!
65
+ ids.reject { |id| id.respond_to?(:empty?) && id.empty? }.map do |id|
66
+ hostgroup_assets << assets.where(:assetable_type => 'Hostgroup', :assetable_id => id).first_or_initialize
72
67
  end
73
- self.assets = hostgroup_assets
68
+ existing_host_assets = self.assets.where(:assetable_type => 'Host::Base')
69
+ self.assets = existing_host_assets + hostgroup_assets
74
70
  end
75
71
 
76
72
  def hostgroups
@@ -93,6 +89,10 @@ module ForemanOpenscap
93
89
  host_ids = hosts.map(&:id).map(&:to_s)
94
90
  end
95
91
 
92
+ def step_to_i(step_name)
93
+ steps.index(step_name) + 1
94
+ end
95
+
96
96
  def steps
97
97
  base_steps = ['Create policy', 'SCAP Content', 'Schedule']
98
98
  base_steps << 'Locations' if SETTINGS[:locations_enabled]
@@ -170,8 +170,37 @@ module ForemanOpenscap
170
170
  }.merge(period_enc)
171
171
  end
172
172
 
173
+ def should_validate?(step_name)
174
+ if new_record? && wizard_initiated?
175
+ step_index > step_to_i(step_name)
176
+ elsif new_record? && !wizard_initiated?
177
+ true
178
+ else
179
+ persisted?
180
+ end
181
+ end
182
+
183
+ def wizard_initiated?
184
+ @wizard_initiated
185
+ end
186
+
187
+ def update_period_attrs
188
+ case period
189
+ when 'monthly'
190
+ erase_period_attrs(['cron_line', 'weekday'])
191
+ when 'weekly'
192
+ erase_period_attrs(['cron_line', 'day_of_month'])
193
+ when 'custom'
194
+ erase_period_attrs(['weekday', 'day_of_month'])
195
+ end
196
+ end
197
+
173
198
  private
174
199
 
200
+ def erase_period_attrs(attrs)
201
+ attrs.each { |attr| self.public_send("#{attr}=", nil) }
202
+ end
203
+
175
204
  def period_enc
176
205
  # get crontab expression as an array (minute hour day_of_month month day_of_week)
177
206
  cron_parts = case period
@@ -221,34 +250,30 @@ module ForemanOpenscap
221
250
  end
222
251
 
223
252
  def cron_line_split
224
- cron_line.split(' ')
253
+ cron_line.to_s.split(' ')
225
254
  end
226
255
 
227
256
  def valid_cron_line
228
- return true if period != 'custom' || step_index != 4
229
-
230
- unless cron_line_split.size == 5
231
- errors[:base] << _("Cron line does not consist of 5 parts separated by space")
232
- return false
257
+ if period == 'custom' && should_validate?('Schedule')
258
+ errors.add(:cron_line, _("does not consist of 5 parts separated by space")) unless cron_line_split.size == 5
233
259
  end
234
260
  end
235
261
 
236
- def ensure_period_specification_present
237
- return true if period.blank? || step_index != 4
262
+ def valid_weekday
263
+ if(period == 'weekly' && should_validate?('Schedule'))
264
+ errors.add(:weekday, _("is not a valid value")) unless Date::DAYNAMES.map(&:downcase).include? weekday
265
+ end
266
+ end
238
267
 
239
- error = nil
240
- error = _("You must fill weekday") if weekday.blank? && period == 'weekday'
241
- error = _("You must fill day of month") if day_of_month.blank? && period == 'monthly'
242
- error = _("You must fill cron line") if cron_line.blank? && period == 'custom'
243
- if error
244
- errors[:base] << error
245
- return false
268
+ def valid_day_of_month
269
+ if(period == 'monthly' && should_validate?('Schedule'))
270
+ errors.add(:day_of_month, _("must be between 1 and 31")) if !day_of_month || (day_of_month < 1 || day_of_month > 31)
246
271
  end
247
272
  end
248
273
 
249
274
  def assign_policy_to_hostgroups
250
275
  if hostgroups.any?
251
- puppetclass = Puppetclass.find_by_name(SCAP_PUPPET_CLASS)
276
+ puppetclass = find_scap_puppetclass
252
277
  hostgroups.each do |hostgroup|
253
278
  hostgroup.puppetclasses << puppetclass unless hostgroup.puppetclasses.include? puppetclass
254
279
  populate_overrides(puppetclass, hostgroup)
@@ -256,6 +281,10 @@ module ForemanOpenscap
256
281
  end
257
282
  end
258
283
 
284
+ def find_scap_puppetclass
285
+ Puppetclass.find_by_name(SCAP_PUPPET_CLASS)
286
+ end
287
+
259
288
  def populate_overrides(puppetclass, hostgroup)
260
289
  puppetclass.class_params.where(:override => true).find_each do |override|
261
290
  next unless hostgroup.puppet_proxy && (url = hostgroup.puppet_proxy.url).present?
@@ -39,15 +39,13 @@ module ForemanOpenscap
39
39
  include Authorizable
40
40
  include Taxonomix
41
41
 
42
- attr_accessible :original_filename, :scap_file, :title, :location_ids, :organization_ids
43
-
44
42
  has_many :scap_content_profiles, :dependent => :destroy
45
43
  has_many :policies
46
44
 
47
45
  before_destroy EnsureNotUsedBy.new(:policies)
48
46
 
49
47
  validates_with DataStreamValidator
50
- validates :title, :presence => true
48
+ validates :title, :presence => true, :length => { :maximum => 255 }
51
49
  validates :digest, :presence => true
52
50
  validates :scap_file, :presence => true
53
51
 
@@ -4,7 +4,7 @@
4
4
  <tr>
5
5
  <th class="ca" width="40px"><%= check_box_tag "check_all", "", false, { :onclick => "toggleCheck()", :'check-title' => _("Select all items in this page"), :'uncheck-title'=> _("items selected. Uncheck to Clear") } %></th>
6
6
  <th><%= sort :host %></th>
7
- <th><%= sort :reported_at, :as => _("Reported At") %></th>
7
+ <th><%= sort :reported, :as => _("Reported At") %></th>
8
8
  <th><%= sort :compliance_passed, :as => _("Passed") %></th>
9
9
  <th><%= sort :compliance_failed, :as => _("Failed") %></th>
10
10
  <th><%= sort :compliance_othered, :as => _("Other") %></th>
@@ -8,9 +8,9 @@
8
8
  <%= render 'output', :logs => @arf_report.logs%>
9
9
  <%= render 'metrics', :status => @arf_report.status, :metrics => @arf_report.metrics if @arf_report.logs.any? %>
10
10
 
11
- <%= title_actions link_to(_('Back'), :back),
11
+ <%= title_actions link_to(_('Back'), :back, :class => "btn btn-default"),
12
12
  display_delete_if_authorized(hash_for_arf_report_path(:id => @arf_report), :class=> "btn btn-danger"),
13
- link_to(_("Host details"), @arf_report.host),
14
- link_to(_("View full report"), show_html_arf_report_path(:id => @arf_report.id)),
15
- link_to(_("Download XML in bzip"), parse_bzip_arf_report_path(:id => @arf_report.id))
13
+ link_to(_("Host details"), @arf_report.host, :class => "btn btn-default"),
14
+ link_to(_("View full report"), show_html_arf_report_path(:id => @arf_report.id), :class => "btn btn-default"),
15
+ link_to(_("Download XML in bzip"), parse_bzip_arf_report_path(:id => @arf_report.id), :class => "btn btn-default")
16
16
  %>
@@ -1,6 +1,6 @@
1
1
  <%= javascript 'dashboard', 'foreman_openscap/scap_hosts_show' %>
2
2
 
3
- <% title n_("%s compliance report by policy", "%s compliance reports by policy"m , host.combined_policies.length) % @host.to_label %>
3
+ <% title n_("%s compliance report by policy", "%s compliance reports by policy" , @host.combined_policies.length) % @host.to_label %>
4
4
  <% @host.combined_policies.each do |policy| %>
5
5
  <h2 class="center-block"><%= _('Policy %s') % policy %></h2>
6
6
  <div class="row">
@@ -1,19 +1,19 @@
1
1
  <h4 class="ca"><%= _('Latest compliance reports') %></h4>
2
- <% latest_reports = ForemanOpenscap::ArfReport.latest %>
2
+ <% latest_reports = ForemanOpenscap::ArfReport.latest.limit(9) %>
3
3
  <% if latest_reports.empty? %>
4
4
  <p class="ca"><%= _("No reports available") %></p>
5
5
  <% else %>
6
6
  <table class="table table-striped ellipsis">
7
7
  <tr>
8
- <%= latest_headers() %>
8
+ <%= latest_compliance_headers %>
9
9
  </tr>
10
10
  <% latest_reports.each do |report| %>
11
11
  <tr>
12
12
  <td><%= link_to h(report.host.nil? ? _('Host does not exist anymore') : report.host.name), arf_report_path(report) %></td>
13
- <td><%= link_to h(report.policy.name), policy_dashboard_policy_path(report.policy) %></td>
14
- <td><%= report_event_column(report.passed, "label-success") %></td>
15
- <td><%= report_event_column(report.failed, "label-danger") %></td>
16
- <td><%= report_event_column(report.othered, "label-info") %></td>
13
+ <td><%= report.policy.nil? ? _('Policy is missing') : link_to(h(report.policy.name), policy_dashboard_policy_path(report.policy)) %></td>
14
+ <td class="ca"><%= report_event_column(report.passed, "label-success") %></td>
15
+ <td class="ca"><%= report_event_column(report.failed, "label-danger") %></td>
16
+ <td class="ca"><%= report_event_column(report.othered, "label-info") %></td>
17
17
  </tr>
18
18
  <% end %>
19
19
  </table>
@@ -2,8 +2,8 @@
2
2
  <% title _("Compliance Policies") %>
3
3
 
4
4
  <% title_actions(
5
- display_link_if_authorized(_("New Compliance Policy"), hash_for_new_policy_path),
6
- link_to(_("Help"), :action => "welcome")
5
+ display_link_if_authorized(_("New Compliance Policy"), hash_for_new_policy_path, :class => "btn btn-default"),
6
+ link_to(_("Help"), { :action => "welcome" }, { :class => "btn btn-info" })
7
7
  ) %>
8
8
 
9
9
  <%= render :partial => 'list' %>