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 +4 -4
- data/app/lib/proxy_api/openscap.rb +11 -0
- data/app/models/concerns/foreman_openscap/compliance_status_scoped_search.rb +6 -2
- data/app/models/concerns/foreman_openscap/data_stream_content.rb +1 -5
- data/app/models/concerns/foreman_openscap/hostgroup_extensions.rb +2 -2
- data/app/models/foreman_openscap/asset.rb +1 -1
- data/app/validators/foreman_openscap/data_stream_validator.rb +1 -1
- data/db/migrate/20240426143215_remove_orphaned_asset_policies.rb +6 -0
- data/lib/foreman_openscap/data_migration.rb +7 -6
- data/lib/foreman_openscap/version.rb +1 -1
- data/test/unit/concerns/hostgroup_extensions_test.rb +10 -0
- data/test/unit/scap_content_test.rb +2 -3
- data/webpack/components/OpenscapRemediationWizard/ViewSelectedHostsLink.js +2 -2
- data/webpack/components/OpenscapRemediationWizard/steps/ReviewHosts.js +20 -2
- data/webpack/components/OpenscapRemediationWizard/steps/ReviewRemediation.js +7 -4
- metadata +5 -3
- data/app/lib/proxy_api/available_proxy.rb +0 -44
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8bbb0c081fe2e68b2a02f8c835f5bbbef162c1f2fa973bc591ad60e27da60884
|
4
|
+
data.tar.gz: 5067c304b892af1d53e7d0ae54e03e831c51f6027e0978058051a1d63e48e5b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 :
|
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 => :
|
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
|
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
|
-
|
9
|
-
has_many :asset_policies, :through => :
|
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
|
|
@@ -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::
|
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.
|
10
|
-
|
11
|
-
|
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
|
-
|
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::
|
51
|
+
rescue *::ProxyAPI::Openscap::HTTP_ERRORS
|
51
52
|
return false
|
52
53
|
end
|
53
54
|
|
@@ -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
|
-
|
30
|
-
|
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 {
|
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(`${
|
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: ({
|
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
|
-
|
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 {
|
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 {
|
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(`${
|
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
|
-
`${
|
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.
|
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-
|
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
|