foreman_openscap 8.0.0 → 8.0.2

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
  SHA256:
3
- metadata.gz: cff46602347754ec7072e88a2033eafc6815b7898909fe6b4e0fc1bd7502749a
4
- data.tar.gz: ae676b964339af51be73f77bdf2be8da05fc7d4250a73fc9d727c5324edc7086
3
+ metadata.gz: 8bbb0c081fe2e68b2a02f8c835f5bbbef162c1f2fa973bc591ad60e27da60884
4
+ data.tar.gz: 5067c304b892af1d53e7d0ae54e03e831c51f6027e0978058051a1d63e48e5b7
5
5
  SHA512:
6
- metadata.gz: 4ff495ee8c3ca45fc5e658e1def666fe971ff6fc2cb8a43f245c6ecbfb579ac0506b2215770eb2c30a95d5e74ae1128f831dfd356f91593fa0b5718940d0b14a
7
- data.tar.gz: 4696593f4916854a2e5b616d8c40dafdaa25b974b07d0067fa0188fdbf8b6541be5768e549735853c348b4f4f5be48b839a16a6183d4ce2f346ca9155ac8c58a
6
+ metadata.gz: 95885c08136b4a8255767661ca869e899c1a115e99912cf613964edce482885b7e6cabc0690e4330fe95745af8fc743fb0314837a540ae2d6fae226311367c78
7
+ data.tar.gz: cef966ada1688c607047f829d512fb329972edaf9d415466f4259d647a9a0758a3e729532c0dbf7bbc732d6272b0aaeeaa607e358de58148a808a9606000dc9d
@@ -1,5 +1,16 @@
1
1
  module ::ProxyAPI
2
2
  class Openscap < ::ProxyAPI::Resource
3
+ HTTP_ERRORS = [
4
+ EOFError,
5
+ Errno::ECONNRESET,
6
+ Errno::EINVAL,
7
+ Net::HTTPBadResponse,
8
+ Net::HTTPHeaderSyntaxError,
9
+ Net::ProtocolError,
10
+ Timeout::Error,
11
+ ProxyAPI::ProxyException
12
+ ].freeze
13
+
3
14
  def initialize(args)
4
15
  @url = args[:url] + '/compliance/'
5
16
  super args
@@ -109,11 +109,15 @@ module ForemanOpenscap
109
109
 
110
110
  included do
111
111
  if ForemanOpenscap.with_katello?
112
- has_one :lifecycle_environment, :through => :host
112
+ has_one :content_facet, :through => :host
113
+ has_many :content_view_environment_content_facets, through: :content_facet, class_name: 'Katello::ContentViewEnvironmentContentFacet'
114
+ has_many :content_view_environments, through: :content_view_environment_content_facets
115
+ has_many :content_views, through: :content_view_environments
116
+ has_many :lifecycle_environments, through: :content_view_environments
113
117
 
114
118
  has_many :host_collections, :through => :host
115
119
 
116
- scoped_search :relation => :lifecycle_environment, :on => :name, :complete_value => true, :rename => :lifecycle_environment
120
+ scoped_search :relation => :lifecycle_environments, :on => :name, :complete_value => true, :rename => :lifecycle_environment
117
121
  scoped_search :relation => :host_collections, :on => :name, :complete_value => true, :rename => :host_collection,
118
122
  :operators => ['= ', '!= '], :ext_method => :search_by_host_collection_name
119
123
  end
@@ -10,11 +10,7 @@ module ForemanOpenscap
10
10
  end
11
11
 
12
12
  def proxy_url
13
- @proxy_url ||= SmartProxy.with_features('Openscap').find do |proxy|
14
- available = ProxyAPI::AvailableProxy.new(:url => proxy.url)
15
- available.available?
16
- end.try(:url)
17
- @proxy_url
13
+ @proxy_url ||= SmartProxy.with_features('Openscap').find(&:ping)&.url
18
14
  end
19
15
 
20
16
  def create_profiles
@@ -5,8 +5,8 @@ module ForemanOpenscap
5
5
  include InheritedPolicies
6
6
 
7
7
  included do
8
- has_one :asset, :as => :assetable, :class_name => "::ForemanOpenscap::Asset", dependent: :destroy
9
- has_many :asset_policies, :through => :asset, :class_name => "::ForemanOpenscap::AssetPolicy"
8
+ has_many :assets, :as => :assetable, :class_name => "::ForemanOpenscap::Asset", dependent: :destroy
9
+ has_many :asset_policies, :through => :assets, :class_name => "::ForemanOpenscap::AssetPolicy"
10
10
  has_many :policies, :through => :asset_policies, :class_name => "::ForemanOpenscap::Policy"
11
11
  end
12
12
 
@@ -1,6 +1,6 @@
1
1
  module ForemanOpenscap
2
2
  class Asset < ApplicationRecord
3
- has_many :asset_policies
3
+ has_many :asset_policies, :dependent => :delete_all
4
4
  has_many :policies, :through => :asset_policies
5
5
  belongs_to :assetable, :polymorphic => true
6
6
 
@@ -22,7 +22,7 @@ module ForemanOpenscap
22
22
  errors['errors'].each { |error| data_stream_content.errors.add(:scap_file, _(error)) }
23
23
  return false
24
24
  end
25
- rescue *ProxyAPI::AvailableProxy::HTTP_ERRORS => e
25
+ rescue *ProxyAPI::Openscap::HTTP_ERRORS => e
26
26
  data_stream_content.errors.add(:base, _('No available proxy to validate. Returned with error: %s') % e)
27
27
  return false
28
28
  end
@@ -0,0 +1,6 @@
1
+ class RemoveOrphanedAssetPolicies < ActiveRecord::Migration[6.0]
2
+ def up
3
+ orphaned_asset_policy_ids = ForemanOpenscap::AssetPolicy.left_outer_joins(:asset).where(asset: { id: nil }).pluck(:asset_id)
4
+ ForemanOpenscap::AssetPolicy.where(asset_id: orphaned_asset_policy_ids).delete_all
5
+ end
6
+ end
@@ -6,14 +6,15 @@ require 'tempfile'
6
6
  module ForemanOpenscap
7
7
  class DataMigration
8
8
  def initialize(proxy_id)
9
- @proxy = ::SmartProxy.find(proxy_id)
10
- puts "Found proxy #{@proxy.to_label}"
11
- @url = @proxy.url
9
+ @proxy = ::SmartProxy.with_features('Openscap').where(id: proxy_id).first
10
+ if @proxy
11
+ puts "Found proxy #{@proxy.to_label}"
12
+ @url = @proxy.url
13
+ end
12
14
  end
13
15
 
14
16
  def available?
15
- return false unless @proxy && @url
16
- ::ProxyAPI::AvailableProxy.new(:url => @url).available? && foreman_available?
17
+ @proxy&.ping && foreman_available?
17
18
  end
18
19
 
19
20
  def migrate
@@ -47,7 +48,7 @@ module ForemanOpenscap
47
48
  foreman_status_url = Setting[:foreman_url] + '/status'
48
49
  response = JSON.parse(RestClient.get(foreman_status_url))
49
50
  return true if response["status"] == "ok"
50
- rescue *::ProxyAPI::AvailableProxy::HTTP_ERRORS
51
+ rescue *::ProxyAPI::Openscap::HTTP_ERRORS
51
52
  return false
52
53
  end
53
54
 
@@ -1,3 +1,3 @@
1
1
  module ForemanOpenscap
2
- VERSION = "8.0.0".freeze
2
+ VERSION = "8.0.2".freeze
3
3
  end
@@ -0,0 +1,10 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class HostgroupExtensionsTest < ActiveSupport::TestCase
4
+ test "should remove all linked assets on hostgroup destroy" do
5
+ hostgroup = FactoryBot.create(:hostgroup)
6
+ FactoryBot.create_list(:asset, 3, :assetable_id => hostgroup.id, :assetable_type => 'Hostgroup')
7
+ asset_scope = ::ForemanOpenscap::Asset.where(:assetable_id => hostgroup.id, :assetable_type => 'Hostgroup')
8
+ assert_difference("asset_scope.count", -3) { hostgroup.destroy }
9
+ end
10
+ end
@@ -17,7 +17,6 @@ class ScapContentTest < ActiveSupport::TestCase
17
17
 
18
18
  test 'scap content should fail if no openscap proxy' do
19
19
  SmartProxy.stubs(:with_features).returns([])
20
- ProxyAPI::AvailableProxy.any_instance.stubs(:available?).returns(false)
21
20
  scap_content = ForemanOpenscap::ScapContent.new(:title => 'Fedora', :scap_file => @scap_file)
22
21
  refute(scap_content.save)
23
22
  assert_includes(scap_content.errors.messages[:base], 'No proxy with OpenSCAP feature was found.')
@@ -26,8 +25,8 @@ class ScapContentTest < ActiveSupport::TestCase
26
25
  test 'proxy_url should return the first available proxy it finds' do
27
26
  available_proxy = SmartProxy.with_features('Openscap').first
28
27
  unavailable_proxy = FactoryBot.create(:smart_proxy, :url => 'http://proxy.example.com:8443', :features => [FactoryBot.create(:feature, :name => 'Openscap')])
29
- available_proxy.stubs(:proxy_url).returns(available_proxy.url)
30
- unavailable_proxy.stubs(:proxy_url).returns(nil)
28
+ SmartProxy.expects(:with_features).with('Openscap').returns([unavailable_proxy, available_proxy])
29
+ SmartProxy.any_instance.expects(:ping).twice.returns(false).then.returns(true)
31
30
  scap_content = ForemanOpenscap::ScapContent.new(:title => 'Fedora', :scap_file => @scap_file)
32
31
  assert_equal(available_proxy.url, scap_content.proxy_url)
33
32
  end
@@ -6,7 +6,7 @@ import { Button } from '@patternfly/react-core';
6
6
 
7
7
  import { translate as __ } from 'foremanReact/common/I18n';
8
8
  import { foremanUrl } from 'foremanReact/common/helpers';
9
- import { getHostsPageUrl } from 'foremanReact/Root/Context/ForemanContext';
9
+ import { useForemanHostsPageUrl } from 'foremanReact/Root/Context/ForemanContext';
10
10
 
11
11
  const ViewSelectedHostsLink = ({
12
12
  hostIdsParam,
@@ -14,7 +14,7 @@ const ViewSelectedHostsLink = ({
14
14
  defaultFailedHostsSearch,
15
15
  }) => {
16
16
  const search = isAllHostsSelected ? defaultFailedHostsSearch : hostIdsParam;
17
- const url = foremanUrl(`${getHostsPageUrl(false)}?search=${search}`);
17
+ const url = foremanUrl(`${useForemanHostsPageUrl()}?search=${search}`);
18
18
  return (
19
19
  <Button
20
20
  component="a"
@@ -1,3 +1,4 @@
1
+ /* eslint-disable camelcase */
1
2
  import React, { useContext, useState, useEffect } from 'react';
2
3
  import PropTypes from 'prop-types';
3
4
  import {
@@ -6,6 +7,7 @@ import {
6
7
  ToolbarContent,
7
8
  ToolbarGroup,
8
9
  ToolbarItem,
10
+ Button,
9
11
  } from '@patternfly/react-core';
10
12
  import { Td } from '@patternfly/react-table';
11
13
  import { toArray } from 'lodash';
@@ -18,6 +20,7 @@ import { useBulkSelect } from 'foremanReact/components/PF4/TableIndexPage/Table/
18
20
  import { getPageStats } from 'foremanReact/components/PF4/TableIndexPage/Table/helpers';
19
21
  import { STATUS } from 'foremanReact/constants';
20
22
  import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
23
+ import { useForemanHostDetailsPageUrl } from 'foremanReact/Root/Context/ForemanContext';
21
24
 
22
25
  import OpenscapRemediationWizardContext from '../OpenscapRemediationWizardContext';
23
26
  import WizardHeader from '../WizardHeader';
@@ -157,14 +160,29 @@ const ReviewHosts = () => {
157
160
  rowData: PropTypes.object.isRequired,
158
161
  };
159
162
 
163
+ const hostDetailsURL = useForemanHostDetailsPageUrl();
160
164
  const columns = {
161
165
  name: {
162
166
  title: __('Name'),
163
- wrapper: ({ id, name }) => <a href={foremanUrl(`hosts/${id}`)}>{name}</a>,
167
+ wrapper: ({ name, display_name: displayName }) => (
168
+ <Button
169
+ component="a"
170
+ variant="link"
171
+ target="_blank"
172
+ href={foremanUrl(`${hostDetailsURL}${name}`)}
173
+ >
174
+ {displayName}
175
+ </Button>
176
+ ),
164
177
  isSorted: true,
178
+ weight: 50,
179
+ isRequired: true,
165
180
  },
166
- operatingsystem_name: {
181
+ os_title: {
167
182
  title: __('OS'),
183
+ wrapper: hostDetails => hostDetails?.operatingsystem_name,
184
+ isSorted: true,
185
+ weight: 200,
168
186
  },
169
187
  };
170
188
 
@@ -16,12 +16,15 @@ import { ExternalLinkSquareAltIcon } from '@patternfly/react-icons';
16
16
 
17
17
  import { translate as __ } from 'foremanReact/common/I18n';
18
18
  import { foremanUrl } from 'foremanReact/common/helpers';
19
- import { getHostsPageUrl } from 'foremanReact/Root/Context/ForemanContext';
19
+ import {
20
+ useForemanHostsPageUrl,
21
+ useForemanHostDetailsPageUrl,
22
+ } from 'foremanReact/Root/Context/ForemanContext';
20
23
 
21
24
  import OpenscapRemediationWizardContext from '../OpenscapRemediationWizardContext';
22
25
  import WizardHeader from '../WizardHeader';
23
26
  import ViewSelectedHostsLink from '../ViewSelectedHostsLink';
24
- import { HOSTS_PATH, FAIL_RULE_SEARCH } from '../constants';
27
+ import { FAIL_RULE_SEARCH } from '../constants';
25
28
  import { findFixBySnippet } from '../helpers';
26
29
 
27
30
  import './ReviewRemediation.scss';
@@ -120,7 +123,7 @@ const ReviewRemediation = () => {
120
123
  iconPosition="right"
121
124
  target="_blank"
122
125
  component="a"
123
- href={foremanUrl(`${getHostsPageUrl(true)}/${hostName}`)}
126
+ href={foremanUrl(`${useForemanHostDetailsPageUrl()}${hostName}`)}
124
127
  >
125
128
  {hostName}
126
129
  </Button>{' '}
@@ -133,7 +136,7 @@ const ReviewRemediation = () => {
133
136
  target="_blank"
134
137
  component="a"
135
138
  href={foremanUrl(
136
- `${HOSTS_PATH}/?search=${FAIL_RULE_SEARCH} = ${source}`
139
+ `${useForemanHostsPageUrl()}?search=${FAIL_RULE_SEARCH} = ${source}`
137
140
  )}
138
141
  >
139
142
  {__('Other hosts failing this rule')}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_openscap
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.0.0
4
+ version: 8.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - slukasik@redhat.com
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-26 00:00:00.000000000 Z
11
+ date: 2024-05-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -105,7 +105,6 @@ files:
105
105
  - app/helpers/policies_helper.rb
106
106
  - app/helpers/policy_dashboard_helper.rb
107
107
  - app/helpers/tailoring_files_helper.rb
108
- - app/lib/proxy_api/available_proxy.rb
109
108
  - app/lib/proxy_api/migration.rb
110
109
  - app/lib/proxy_api/openscap.rb
111
110
  - app/mailers/foreman_openscap/policy_mailer.rb
@@ -326,6 +325,7 @@ files:
326
325
  - db/migrate/20210409095625_add_oval_policy_reference_to_cve.rb
327
326
  - db/migrate/20210819143316_drop_unused_tables.rb
328
327
  - db/migrate/20230912122310_add_fixes_to_message.rb
328
+ - db/migrate/20240426143215_remove_orphaned_asset_policies.rb
329
329
  - db/seeds.d/75-job_templates.rb
330
330
  - db/seeds.d/openscap_feature.rb
331
331
  - db/seeds.d/openscap_policy_notification.rb
@@ -449,6 +449,7 @@ files:
449
449
  - test/unit/arf_report_test.rb
450
450
  - test/unit/compliance_status_test.rb
451
451
  - test/unit/concerns/host_extensions_test.rb
452
+ - test/unit/concerns/hostgroup_extensions_test.rb
452
453
  - test/unit/concerns/openscap_proxy_extenstions_test.rb
453
454
  - test/unit/message_cleaner_test.rb
454
455
  - test/unit/openscap_host_test.rb
@@ -635,6 +636,7 @@ test_files:
635
636
  - test/unit/arf_report_test.rb
636
637
  - test/unit/compliance_status_test.rb
637
638
  - test/unit/concerns/host_extensions_test.rb
639
+ - test/unit/concerns/hostgroup_extensions_test.rb
638
640
  - test/unit/concerns/openscap_proxy_extenstions_test.rb
639
641
  - test/unit/message_cleaner_test.rb
640
642
  - test/unit/openscap_host_test.rb
@@ -1,44 +0,0 @@
1
- module ::ProxyAPI
2
- class AvailableProxy
3
- HTTP_ERRORS = [
4
- EOFError,
5
- Errno::ECONNRESET,
6
- Errno::EINVAL,
7
- Net::HTTPBadResponse,
8
- Net::HTTPHeaderSyntaxError,
9
- Net::ProtocolError,
10
- Timeout::Error,
11
- ProxyAPI::ProxyException
12
- ].freeze
13
-
14
- def initialize(args)
15
- @args = args
16
- end
17
-
18
- def available?
19
- begin
20
- return true if has_scap_feature? && minimum_version
21
- rescue *HTTP_ERRORS
22
- return false
23
- end
24
- false
25
- end
26
-
27
- private
28
-
29
- def has_scap_feature?
30
- @features ||= ::ProxyAPI::Features.new(@args).features
31
- @features.include?('openscap')
32
- end
33
-
34
- def openscap_proxy_version
35
- @versions ||= ::ProxyAPI::Version.new(@args).proxy_versions['modules']
36
- @versions['openscap'] if @versions && @versions['openscap']
37
- end
38
-
39
- def minimum_version
40
- return false unless openscap_proxy_version
41
- openscap_proxy_version.to_f >= 0.5
42
- end
43
- end
44
- end