foreman_openscap 0.4.0 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 48ae466c6c227a222397d8a8151177798cf1a035
4
- data.tar.gz: 6abafa02b5291e3b1aa4c36a682e4ea931ccd646
3
+ metadata.gz: 92cfa722f49b4849b12e6de9b12752f7403250c9
4
+ data.tar.gz: 216d2b98129dc7cf0de15c0c294522d8147e3a7c
5
5
  SHA512:
6
- metadata.gz: d3c84160ddb908cd9f928878bed4f11c14e9691fe827f072795003e1bc97687db1c2ce33826b57a3ef64997c10bd7d4e44aa5b9d505da02bf9b0145e53511e85
7
- data.tar.gz: e9fcbe1028267dbc7ca0d548e41d4390309e540465609eefe739a3fce064566119d72a8fc498e6174697057be2642520839f1f15227ca1e1ac09fcf7fafc0af5
6
+ metadata.gz: 8c90cfa657a43e9490a5246dc8a195d0476b2d2c84ff33c97ffc633c96af029a8ebe71f87b5bc980212192a25aa50bd773d19b01648fea3082f186120e05713a
7
+ data.tar.gz: b7044c839f2b328e2591f93dc85081f1cc97fded7d0346ed5ab0afdc1896bd4cb82c168ad3af354976e4fb6eaf76c8c3bd1c6f9b0fc0ec558f582257b0df6f50
@@ -70,6 +70,16 @@ module Api::V2
70
70
  process_response @policy.destroy
71
71
  end
72
72
 
73
+ api :GET, '/compliance/policies/:id/content', N_("Show a policy's SCAP content")
74
+ param :id, :identifier, :required => true
75
+
76
+ def content
77
+ @scap_content = @policy.scap_content
78
+ send_data @scap_content.scap_file,
79
+ :type => 'application/xml',
80
+ :filename => @scap_content.original_filename
81
+ end
82
+
73
83
  private
74
84
  def find_resource
75
85
  not_found and return if params[:id].blank?
@@ -26,7 +26,7 @@ module ForemanOpenscap
26
26
  end
27
27
 
28
28
  def combined_policies
29
- combined = self.policies + self.hostgroup.policies
29
+ combined = self.hostgroup ? self.policies + self.hostgroup.policies : self.policies
30
30
  combined.uniq
31
31
  end
32
32
 
@@ -19,19 +19,19 @@ module ForemanOpenscap
19
19
  attr_accessible :location_ids, :organization_ids, :current_step, :hostgroup_ids
20
20
  attr_writer :current_step
21
21
 
22
- SCAP_PUPPET_CLASS = 'foreman_scap_client'
22
+ SCAP_PUPPET_CLASS = 'foreman_scap_client'
23
23
  POLICIES_CLASS_PARAMETER = 'policies'
24
- SERVER_CLASS_PARAMETER = 'server'
25
- PORT_CLASS_PARAMETER = 'port'
24
+ SERVER_CLASS_PARAMETER = 'server'
25
+ PORT_CLASS_PARAMETER = 'port'
26
26
 
27
- validates :name, :presence => true, :uniqueness => true, :format => { without: /\s/ }
27
+ validates :name, :presence => true, :uniqueness => true, :format => {without: /\s/}
28
28
  validate :ensure_needed_puppetclasses
29
29
  validates :period, :inclusion => {:in => %w[weekly monthly custom]},
30
- :if => Proc.new { | policy | policy.new_record? ? policy.step_index > 3 : !policy.id.blank? }
30
+ :if => Proc.new { |policy| policy.new_record? ? policy.step_index > 3 : !policy.id.blank? }
31
31
  validates :weekday, :inclusion => {:in => Date::DAYNAMES.map(&:downcase)},
32
- :if => Proc.new { | policy | policy.period == 'weekly' && (policy.new_record? ? policy.step_index > 3 : !policy.id.blank?) }
32
+ :if => Proc.new { |policy| policy.period == 'weekly' && (policy.new_record? ? policy.step_index > 3 : !policy.id.blank?) }
33
33
  validates :day_of_month, :numericality => {:greater_than => 0, :less_than => 32},
34
- :if => Proc.new { | policy | policy.period == 'monthly'&& (policy.new_record? ? policy.step_index > 3 : !policy.id.blank?) }
34
+ :if => Proc.new { |policy| policy.period == 'monthly'&& (policy.new_record? ? policy.step_index > 3 : !policy.id.blank?) }
35
35
  validate :valid_cron_line
36
36
  validate :ensure_period_specification_present
37
37
 
@@ -82,7 +82,7 @@ module ForemanOpenscap
82
82
  end
83
83
 
84
84
  def next_step
85
- steps[steps.index(current_step) + 1 ]
85
+ steps[steps.index(current_step) + 1]
86
86
  end
87
87
 
88
88
  def rewind_step
@@ -111,14 +111,14 @@ module ForemanOpenscap
111
111
 
112
112
  def used_location_ids
113
113
  Location.joins(:taxable_taxonomies).where(
114
- 'taxable_taxonomies.taxable_type' => 'Scaptimony::Policy',
115
- 'taxable_taxonomies.taxable_id' => id).pluck("#{Location.arel_table.name}.id")
114
+ 'taxable_taxonomies.taxable_type' => 'Scaptimony::Policy',
115
+ 'taxable_taxonomies.taxable_id' => id).pluck("#{Location.arel_table.name}.id")
116
116
  end
117
117
 
118
118
  def used_organization_ids
119
119
  Organization.joins(:taxable_taxonomies).where(
120
- 'taxable_taxonomies.taxable_type' => 'Scaptimony::Policy',
121
- 'taxable_taxonomies.taxable_id' => id).pluck("#{Location.arel_table.name}.id")
120
+ 'taxable_taxonomies.taxable_type' => 'Scaptimony::Policy',
121
+ 'taxable_taxonomies.taxable_id' => id).pluck("#{Location.arel_table.name}.id")
122
122
  end
123
123
 
124
124
  def used_hostgroup_ids
@@ -136,9 +136,10 @@ module ForemanOpenscap
136
136
 
137
137
  def to_enc
138
138
  {
139
- 'id' => self.id,
140
- 'profile_id' => self.scap_content_profile.try(:profile_id) || '',
141
- 'content_path' => "/var/lib/openscap/content/#{self.scap_content.digest}.xml",
139
+ 'id' => self.id,
140
+ 'profile_id' => self.scap_content_profile.try(:profile_id) || '',
141
+ 'content_path' => "/var/lib/openscap/content/#{self.scap_content.digest}.xml",
142
+ 'download_path' => "/compliance/policies/#{self.id}/content" # default to proxy path
142
143
  }.merge(period_enc)
143
144
  end
144
145
 
@@ -147,22 +148,22 @@ module ForemanOpenscap
147
148
  def period_enc
148
149
  # get crontab expression as an array (minute hour day_of_month month day_of_week)
149
150
  cron_parts = case period
150
- when 'weekly'
151
- [ '0', '1', '*', '*', weekday_number.to_s ]
152
- when 'monthly'
153
- [ '0', '1', day_of_month.to_s, '*', '*']
154
- when 'custom'
155
- cron_line_split
156
- else
157
- raise 'invalid period specification'
158
- end
151
+ when 'weekly'
152
+ ['0', '1', '*', '*', weekday_number.to_s]
153
+ when 'monthly'
154
+ ['0', '1', day_of_month.to_s, '*', '*']
155
+ when 'custom'
156
+ cron_line_split
157
+ else
158
+ raise 'invalid period specification'
159
+ end
159
160
 
160
161
  {
161
- 'minute' => cron_parts[0],
162
- 'hour' => cron_parts[1],
163
- 'monthday' => cron_parts[2],
164
- 'month' => cron_parts[3],
165
- 'weekday' => cron_parts[4],
162
+ 'minute' => cron_parts[0],
163
+ 'hour' => cron_parts[1],
164
+ 'monthday' => cron_parts[2],
165
+ 'month' => cron_parts[3],
166
+ 'weekday' => cron_parts[4],
166
167
  }
167
168
  end
168
169
 
@@ -182,8 +183,8 @@ module ForemanOpenscap
182
183
  return false
183
184
  end
184
185
 
185
- policies_param.override = true
186
- policies_param.key_type = 'array'
186
+ policies_param.override = true
187
+ policies_param.key_type = 'array'
187
188
  policies_param.default_value = '<%= @host.policies_enc %>'
188
189
 
189
190
  if policies_param.changed? && !policies_param.save
@@ -233,11 +234,11 @@ module ForemanOpenscap
233
234
  if hostgroup.puppet_proxy && (url = hostgroup.puppet_proxy.url).present?
234
235
  case override.key
235
236
  when SERVER_CLASS_PARAMETER
236
- lookup_value = LookupValue.where(:match => "hostgroup=#{hostgroup.to_label}", :lookup_key_id => override.id).first_or_initialize
237
+ lookup_value = LookupValue.where(:match => "hostgroup=#{hostgroup.to_label}", :lookup_key_id => override.id).first_or_initialize
237
238
  puppet_proxy_fqdn = URI.parse(url).host
238
239
  lookup_value.update_attribute(:value, puppet_proxy_fqdn)
239
240
  when PORT_CLASS_PARAMETER
240
- lookup_value = LookupValue.where(:match => "hostgroup=#{hostgroup.to_label}", :lookup_key_id => override.id).first_or_initialize
241
+ lookup_value = LookupValue.where(:match => "hostgroup=#{hostgroup.to_label}", :lookup_key_id => override.id).first_or_initialize
241
242
  puppet_proxy_port = URI.parse(url).port
242
243
  lookup_value.update_attribute(:value, puppet_proxy_port)
243
244
  end
@@ -13,7 +13,7 @@
13
13
  </tr>
14
14
  <% latest_reports.each do |report| %>
15
15
  <tr>
16
- <td><%= link_to h(report.host.name), scaptimony_arf_report_path(report) %></td>
16
+ <td><%= link_to h(report.host.nil? ? _('Host does not exist anymore') : report.host.name), scaptimony_arf_report_path(report) %></td>
17
17
  <td><%= link_to h(report.policy.name), scaptimony_policy_dashboard_scaptimony_policy_path(report.policy) %></td>
18
18
  <td><%= report_event_column(report.passed, "label-success") %></td>
19
19
  <td><%= report_event_column(report.failed, "label-danger") %></td>
@@ -9,7 +9,7 @@
9
9
  </tr>
10
10
  <% for arf_report in @arf_reports %>
11
11
  <tr>
12
- <td><%= name_column(arf_report.host) %></td>
12
+ <td><%= arf_report.host.nil? ? _('Host does not exist anymore') : name_column(arf_report.host) %></td>
13
13
  <td><%= _("%s ago") % time_ago_in_words(arf_report.date) %></td>
14
14
  <td><%= report_arf_column(arf_report.passed, "label-info") %></th>
15
15
  <td><%= report_arf_column(arf_report.failed, "label-danger") %></th>
@@ -2,24 +2,21 @@
2
2
 
3
3
  <% title _("Compliance policy: %s") % @policy.name %>
4
4
 
5
- <div id='dashboard' class="row gridster">
5
+ <div id='dashboard' class="gridster col-md-12 ready">
6
6
  <ul>
7
- <%= policy_widget_list.map do |widget|
8
- content_tag(:li, render(widget.id), :data => {
9
- :id => widget.id,
10
- :name => widget.name || widget.id,
11
- :row => widget.row,
12
- :col => widget.col,
13
- :sizex => widget.sizex,
14
- :sizey => widget.sizey,
15
- :hide => widget.hide
16
- })
17
- end.join(' ').html_safe
18
- %>
7
+ <% [{:template => 'policy_status_widget', :sizex => 8, :sizey => 1, :name => N_('Status table')},
8
+ {:template => 'policy_chart_widget', :sizex => 4, :sizey => 1, :name => N_('Status chart')}].each do |w| %>
9
+ <% widget = Widget.new(w) %>
10
+ <%= content_tag(:li, widget_data(widget)) do %>
11
+ <div class="widget <%= widget.name.parameterize %>">
12
+ <%= render_widget(widget) %>
13
+ </div>
14
+ <% end %>
15
+ <% end %>
19
16
  </ul>
20
17
  </div>
21
18
  <% if @policy.arf_reports.any? %>
22
- <div class="row gridster">
19
+ <div class="col-md-12 gridster">
23
20
  <%= _("Latest reports for policy: %s") % @policy.name %>
24
21
  <%= render :partial => 'policy_reports' %>
25
22
  </div>
data/config/routes.rb CHANGED
@@ -40,7 +40,11 @@ Rails.application.routes.draw do
40
40
  :apiv => /v1|v2/, :constraints => ApiConstraints.new(:version => 2) do
41
41
  namespace :compliance do
42
42
  resources :scap_contents, :except => [:new, :edit]
43
- resources :policies, :except => [:new, :edit]
43
+ resources :policies, :except => [:new, :edit] do
44
+ member do
45
+ get 'content'
46
+ end
47
+ end
44
48
  resources :arf_reports, :only => [:index, :show, :destroy]
45
49
  post 'arf_reports/:cname/:policy_id/:date', \
46
50
  :constraints => { :cname => /[^\/]+/ }, :to => 'arf_reports#create'
@@ -0,0 +1,2 @@
1
+ require 'foreman_openscap/bulk_upload'
2
+ ForemanOpenscap::BulkUpload.new(true).generate_scap_default_content
@@ -0,0 +1,62 @@
1
+ require 'digest/sha2'
2
+ module ForemanOpenscap
3
+ class BulkUpload
4
+ attr_accessor :from_scap_security_guide
5
+ def initialize(from_scap_security_guide=false)
6
+ @from_scap_security_guide = from_scap_security_guide
7
+ end
8
+
9
+ def generate_scap_default_content
10
+ return unless @from_scap_security_guide
11
+
12
+ if `rpm -qa | grep scap-security-guide`.empty?
13
+ Rails.logger.debug "Can't find scap-security-guide RPM"
14
+ return
15
+ end
16
+
17
+ files_array = `rpm -ql scap-security-guide | grep ds.xml`.split
18
+ upload_from_files(files_array) unless files_array.empty?
19
+ end
20
+
21
+ def upload_from_files(files_array)
22
+ files_array.each do |datastream|
23
+ file = File.open(datastream, 'rb').read
24
+ digest = Digest::SHA2.hexdigest(datastream)
25
+ title = content_name(datastream)
26
+ filename = original_filename(datastream)
27
+ scap_content = Scaptimony::ScapContent.where(:title => title, :digest => digest, :scap_file => file).first_or_initialize
28
+ unless scap_content.persisted?
29
+ scap_content.original_filename = filename
30
+ next puts "## SCAP content is invalid: #{scap_content.errors.full_messages.uniq.join(',')} ##" unless scap_content.valid?
31
+ if scap_content.save
32
+ puts "Saved #{datastream} as #{scap_content.title}"
33
+ else
34
+ puts "Failed saving #{datastream}"
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ def upload_from_directory(directory_path)
41
+ files_array = Dir["#{directory_path}/*-ds.xml"]
42
+ upload_from_files(files_array) unless files_array.empty?
43
+ end
44
+
45
+ private
46
+
47
+ def extract_name_from_file(file)
48
+ # SCAP datastream files are in format of ssg-<OS>-ds.xml
49
+ # We wish to extract the <OS> and create a name of it
50
+ original_filename(file).gsub('ssg-','').gsub('-ds.xml', '')
51
+ end
52
+
53
+ def original_filename(file)
54
+ file.split('/').last
55
+ end
56
+
57
+ def content_name(datastream)
58
+ os_name = extract_name_from_file(datastream)
59
+ @from_scap_security_guide ? "Red Hat #{os_name} default content" : "#{os_name} content"
60
+ end
61
+ end
62
+ end
@@ -10,8 +10,25 @@
10
10
 
11
11
  module ForemanOpenscap::Helper
12
12
  def self.get_asset(cname, policy_id)
13
- asset = Host.find_by_name!(cname).get_asset
13
+ asset = find_host_by_name_or_uuid(cname).get_asset
14
14
  asset.policy_ids += [policy_id]
15
15
  asset
16
16
  end
17
+
18
+ private
19
+
20
+ def self.find_host_by_name_or_uuid(cname)
21
+ if defined?(Katello::System)
22
+ host = Host.includes(:content_host).where(:katello_systems => {:uuid => cname}).first
23
+ host ||= Host.find_by_name(cname)
24
+ else
25
+ host = Host.find_by_name(cname)
26
+ end
27
+ unless host
28
+ Rails.logger.error "Could not find Host with name: #{cname}"
29
+ Rails.logger.error "Please check that Content host is linked to Foreman host" if defined?(Katello::System)
30
+ raise ActiveRecord::RecordNotFound
31
+ end
32
+ host
33
+ end
17
34
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanOpenscap
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.1"
3
3
  end
@@ -1,9 +1,19 @@
1
1
  # Tasks
2
2
  namespace :foreman_openscap do
3
- namespace :example do
4
- desc 'Example Task'
5
- task :task => :environment do
6
- # Task goes here
3
+ require 'foreman_openscap/bulk_upload'
4
+ namespace :bulk_upload do
5
+ desc 'Bulk upload SCAP content from directory'
6
+ task :directory, [:directory] => [:environment] do |task, args|
7
+ abort("# No such directory, please check the path you have provided. #") unless args[:directory].blank? || Dir.exist?(args[:directory])
8
+ ForemanOpenscap::BulkUpload.new.upload_from_directory(args[:directory])
9
+ end
10
+
11
+ task :files, [:files] => [:environment] do |task, args|
12
+ files_array = args[:files].split(' ')
13
+ files_array.each do |file|
14
+ abort("# #{file} is a directory, expecting file. Try using 'rake foreman_openscap:bulk_upload:directory' with this directory. #") if File.directory?(file)
15
+ end
16
+ ForemanOpenscap::BulkUpload.new.upload_from_files(files_array)
7
17
  end
8
18
  end
9
19
  end
@@ -55,4 +55,11 @@ class Api::V2::PoliciesControllerTest < ActionController::TestCase
55
55
  assert_response :ok
56
56
  refute Scaptimony::Policy.exists?(policy.id)
57
57
  end
58
+
59
+ test "should return xml of scap content" do
60
+ policy = FactoryGirl.create(:policy)
61
+ get :content, { :id => policy.id }, set_session_user
62
+ assert(@response.header['Content-Type'], 'application/xml')
63
+ assert_response :success
64
+ end
58
65
  end
metadata CHANGED
@@ -1,41 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_openscap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
- - "Šimon Lukašík"
7
+ - Šimon Lukašík
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-25 00:00:00.000000000 Z
11
+ date: 2015-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deface
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ~>
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: scaptimony
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ~>
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.3.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ~>
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.3.0
41
41
  description: Foreman plug-in for managing security compliance reports
@@ -75,8 +75,6 @@ files:
75
75
  - app/overrides/hosts/overview/host_compliance_status.rb
76
76
  - app/services/scaptimony/host_report_dashboard/data.rb
77
77
  - app/services/scaptimony/policy_dashboard/data.rb
78
- - app/services/scaptimony/policy_dashboard/loader.rb
79
- - app/services/scaptimony/policy_dashboard/manager.rb
80
78
  - app/services/scaptimony/report_dashboard/data.rb
81
79
  - app/views/api/v2/compliance/arf_reports/base.json.rabl
82
80
  - app/views/api/v2/compliance/arf_reports/index.json.rabl
@@ -128,7 +126,9 @@ files:
128
126
  - app/views/scaptimony_scap_contents/welcome.html.erb
129
127
  - config/routes.rb
130
128
  - db/seeds.d/openscap_feature.rb
129
+ - db/seeds.d/openscap_scap_default.rb
131
130
  - lib/foreman_openscap.rb
131
+ - lib/foreman_openscap/bulk_upload.rb
132
132
  - lib/foreman_openscap/engine.rb
133
133
  - lib/foreman_openscap/helper.rb
134
134
  - lib/foreman_openscap/version.rb
@@ -153,12 +153,12 @@ require_paths:
153
153
  - lib
154
154
  required_ruby_version: !ruby/object:Gem::Requirement
155
155
  requirements:
156
- - - ">="
156
+ - - '>='
157
157
  - !ruby/object:Gem::Version
158
158
  version: '0'
159
159
  required_rubygems_version: !ruby/object:Gem::Requirement
160
160
  requirements:
161
- - - ">="
161
+ - - '>='
162
162
  - !ruby/object:Gem::Version
163
163
  version: '0'
164
164
  requirements: []
@@ -168,14 +168,14 @@ signing_key:
168
168
  specification_version: 4
169
169
  summary: Foreman plug-in for displaying OpenSCAP audit reports
170
170
  test_files:
171
- - test/unit/openscap_host_test.rb
172
- - test/test_plugin_helper.rb
173
- - test/files/scap_contents/ssg-fedora-ds.xml
174
- - test/functional/api/v2/arf_reports_controller_test.rb
175
- - test/functional/api/v2/scap_contents_controller_test.rb
176
- - test/functional/api/v2/policies_controller_test.rb
177
- - test/factories/asset_factory.rb
178
171
  - test/factories/policy_factory.rb
172
+ - test/factories/asset_factory.rb
179
173
  - test/factories/scap_content_related.rb
180
174
  - test/factories/arf_report_factory.rb
175
+ - test/unit/openscap_host_test.rb
176
+ - test/files/scap_contents/ssg-fedora-ds.xml
177
+ - test/functional/api/v2/policies_controller_test.rb
178
+ - test/functional/api/v2/scap_contents_controller_test.rb
179
+ - test/functional/api/v2/arf_reports_controller_test.rb
180
+ - test/test_plugin_helper.rb
181
181
  has_rdoc:
@@ -1,20 +0,0 @@
1
- #
2
- # Copyright (c) 2014 Red Hat Inc.
3
- #
4
- # This software is licensed to you under the GNU General Public License,
5
- # version 3 (GPLv3). There is NO WARRANTY for this software, express or
6
- # implied, including the implied warranties of MERCHANTABILITY or FITNESS
7
- # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv3
8
- # along with this software; if not, see http://www.gnu.org/licenses/gpl.txt
9
- #
10
-
11
- module Scaptimony::PolicyDashboard
12
- class Loader
13
- def self.load
14
- Scaptimony::PolicyDashboard::Manager.map do |dashboard|
15
- dashboard.widget 'policy_status_widget', :row=>1,:col=>1,:sizex=>8,:sizey=>1,:name=> N_('Status table')
16
- dashboard.widget 'policy_chart_widget', :row=>1,:col=>9,:sizex=>4,:sizey=>1,:name=> N_('Status chart')
17
- end
18
- end
19
- end
20
- end
@@ -1,32 +0,0 @@
1
- #
2
- # Copyright (c) 2014 Red Hat Inc.
3
- #
4
- # This software is licensed to you under the GNU General Public License,
5
- # version 3 (GPLv3). There is NO WARRANTY for this software, express or
6
- # implied, including the implied warranties of MERCHANTABILITY or FITNESS
7
- # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv3
8
- # along with this software; if not, see http://www.gnu.org/licenses/gpl.txt
9
- #
10
-
11
- module Scaptimony::PolicyDashboard
12
- module Manager
13
- class << self
14
- def map
15
- @widgets ||= []
16
- mapper = Mapper.new(@widgets)
17
- if block_given?
18
- yield mapper
19
- else
20
- mapper
21
- end
22
- end
23
-
24
- def widgets
25
- @widgets ||= Scaptimony::PolicyDashboard::Loader.load
26
- end
27
- end
28
-
29
- class Mapper < ::Dashboard::Manager::Mapper
30
- end
31
- end
32
- end