foreman_openscap 0.5.4 → 0.6.0

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