foreman_rh_cloud 14.1.2 → 14.1.3
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/lib/foreman_inventory_upload/generators/fact_helpers.rb +26 -4
- data/lib/foreman_inventory_upload.rb +8 -1
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/lib/foreman_rh_cloud.rb +36 -9
- data/lib/insights_cloud/async/insights_generate_notifications.rb +10 -1
- data/lib/inventory_sync/async/inventory_self_host_sync.rb +12 -2
- data/package.json +1 -1
- data/test/jobs/insights_generate_notifications_test.rb +26 -0
- data/test/jobs/inventory_self_host_sync_test.rb +9 -0
- data/test/unit/foreman_rh_cloud_self_host_test.rb +50 -2
- data/test/unit/metadata_generator_test.rb +24 -1
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyResults/__tests__/EmptyResults.test.js +10 -9
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyState/__tests__/EmptyState.test.js +13 -9
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ErrorState/__tests__/ErrorState.test.js +20 -9
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItem/__tests__/ListItem.test.js +31 -8
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItemStatus/__tests__/ListItemStatus.test.js +26 -10
- data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountList.test.js +33 -9
- data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountListReducer.test.js +55 -35
- data/webpack/ForemanInventoryUpload/Components/FileDownload/__tests__/FileDownload.test.js +13 -9
- data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/InventoryFilter.test.js +12 -15
- data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/integration.test.js +32 -12
- data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/PageTitle.test.js +14 -7
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/__tests__/CloudConnectorButton.test.js +47 -18
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SettingsWarning/SettingsWarning.test.js +58 -15
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/SyncButton.test.js +23 -9
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/SyncButtonSelectors.test.js +19 -17
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/integrations.test.js +25 -37
- data/webpack/ForemanInventoryUpload/Components/ScheduledRun/__tests__/ScheduledRun.test.js +28 -8
- data/webpack/ForemanInventoryUpload/Components/StatusChart/__tests__/StatusChart.test.js +25 -8
- data/webpack/ForemanInventoryUpload/Components/TabContainer/__tests__/TabContainer.test.js +11 -9
- data/webpack/ForemanInventoryUpload/Components/TabFooter/__tests__/TabFooter.test.js +11 -9
- data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/__tests__/InventoryAutoUpload.test.js +33 -12
- data/webpack/ForemanInventoryUpload/__tests__/ForemanInventoryHelpers.test.js +21 -8
- data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/InsightsSettingsActions.test.js +61 -47
- data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/InsightsTable.test.js +48 -4
- data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/InsightsTableActions.test.js +126 -35
- data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/InsightsTableSelectors.test.js +90 -24
- data/webpack/InsightsCloudSync/InsightsCloudSync.test.js +79 -21
- data/webpack/InsightsCloudSync/__tests__/InsightsCloudSyncActions.test.js +31 -6
- data/webpack/InsightsHostDetailsTab/__tests__/InsightsTab.test.js +42 -9
- data/webpack/__tests__/ForemanRhCloudHelpers.test.js +91 -53
- data/webpack/common/Switcher/__tests__/HelpLabel.test.js +25 -10
- data/webpack/common/Switcher/__tests__/SwitcherPF4.test.js +41 -10
- metadata +3 -67
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyResults/__tests__/__snapshots__/EmptyResults.test.js.snap +0 -18
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/EmptyState/__tests__/__snapshots__/EmptyState.test.js.snap +0 -25
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ErrorState/__tests__/__snapshots__/ErrorState.test.js.snap +0 -20
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItem/__tests__/__snapshots__/ListItem.test.js.snap +0 -47
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItemStatus/__tests__/__snapshots__/ListItemStatus.test.js.snap +0 -59
- data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountListActions.test.js +0 -34
- data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountListIntegration.test.js +0 -14
- data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/AccountListSelectors.test.js +0 -25
- data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountList.test.js.snap +0 -49
- data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountListActions.test.js.snap +0 -86
- data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountListReducer.test.js.snap +0 -75
- data/webpack/ForemanInventoryUpload/Components/AccountList/__tests__/__snapshots__/AccountListSelectors.test.js.snap +0 -46
- data/webpack/ForemanInventoryUpload/Components/FileDownload/__tests__/__snapshots__/FileDownload.test.js.snap +0 -26
- data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/InventoryFilterActions.test.js +0 -14
- data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/InventoryFilterReducer.test.js +0 -28
- data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/InventoryFilterSelectors.test.js +0 -21
- data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/InventoryFilter.test.js.snap +0 -21
- data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/InventoryFilterActions.test.js.snap +0 -17
- data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/InventoryFilterReducer.test.js.snap +0 -19
- data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/InventoryFilterSelectors.test.js.snap +0 -9
- data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/integration.test.js.snap +0 -43
- data/webpack/ForemanInventoryUpload/Components/InventorySettings/AdvancedSetting/__tests__/AdvancedSettingActions.test.js +0 -9
- data/webpack/ForemanInventoryUpload/Components/InventorySettings/AdvancedSetting/__tests__/__snapshots__/AdvancedSettingActions.test.js.snap +0 -18
- data/webpack/ForemanInventoryUpload/Components/InventorySettings/__tests__/InventorySettingsActions.test.js +0 -14
- data/webpack/ForemanInventoryUpload/Components/InventorySettings/__tests__/__snapshots__/InventorySettingsActions.test.js.snap +0 -26
- data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageTitle.test.js.snap +0 -68
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/__tests__/CloudConnectorActions.test.js +0 -9
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/__tests__/__snapshots__/CloudConnectorActions.test.js.snap +0 -11
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/__tests__/__snapshots__/CloudConnectorButton.test.js.snap +0 -59
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SettingsWarning/__snapshots__/SettingsWarning.test.js.snap +0 -32
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/SyncButton.test.js.snap +0 -15
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/SyncButtonSelectors.test.js.snap +0 -3
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/integrations.test.js.snap +0 -58
- data/webpack/ForemanInventoryUpload/Components/ScheduledRun/__tests__/__snapshots__/ScheduledRun.test.js.snap +0 -23
- data/webpack/ForemanInventoryUpload/Components/StatusChart/__tests__/__snapshots__/StatusChart.test.js.snap +0 -74
- data/webpack/ForemanInventoryUpload/Components/TabContainer/__tests__/__snapshots__/TabContainer.test.js.snap +0 -18
- data/webpack/ForemanInventoryUpload/Components/TabFooter/__tests__/__snapshots__/TabFooter.test.js.snap +0 -12
- data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/__tests__/__snapshots__/InventoryAutoUpload.test.js.snap +0 -96
- data/webpack/ForemanInventoryUpload/__tests__/ForemanInventoryUpload.test.js +0 -10
- data/webpack/ForemanInventoryUpload/__tests__/__snapshots__/ForemanInventoryHelpers.test.js.snap +0 -5
- data/webpack/ForemanInventoryUpload/__tests__/__snapshots__/ForemanInventoryUpload.test.js.snap +0 -14
- data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/InsightsSettingsReducer.test.js +0 -33
- data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/InsightsSettingsSelectors.test.js +0 -21
- data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/__snapshots__/InsightsSettingsActions.test.js.snap +0 -65
- data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/__snapshots__/InsightsSettingsReducer.test.js.snap +0 -19
- data/webpack/InsightsCloudSync/Components/InsightsSettings/__tests__/__snapshots__/InsightsSettingsSelectors.test.js.snap +0 -9
- data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTableActions.test.js.snap +0 -131
- data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTableSelectors.test.js.snap +0 -87
- data/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap +0 -10
- data/webpack/InsightsCloudSync/__tests__/InsightsCloudSyncHelpers.test.js +0 -9
- data/webpack/InsightsCloudSync/__tests__/__snapshots__/InsightsCloudSyncActions.test.js.snap +0 -15
- data/webpack/InsightsCloudSync/__tests__/__snapshots__/InsightsCloudSyncHelpers.test.js.snap +0 -3
- data/webpack/InsightsHostDetailsTab/__tests__/InsightsTabActions.test.js +0 -19
- data/webpack/InsightsHostDetailsTab/__tests__/InsightsTabReducer.test.js +0 -26
- data/webpack/InsightsHostDetailsTab/__tests__/InsightsTabSelectors.test.js +0 -13
- data/webpack/InsightsHostDetailsTab/__tests__/__snapshots__/InsightsTab.test.js.snap +0 -34
- data/webpack/InsightsHostDetailsTab/__tests__/__snapshots__/InsightsTabActions.test.js.snap +0 -56
- data/webpack/InsightsHostDetailsTab/__tests__/__snapshots__/InsightsTabReducer.test.js.snap +0 -32
- data/webpack/InsightsHostDetailsTab/__tests__/__snapshots__/InsightsTabSelectors.test.js.snap +0 -18
- data/webpack/__tests__/ForemanRhCloudSelectors.test.js +0 -22
- data/webpack/__tests__/ForemanRhCloudTestHelpers.test.js +0 -20
- data/webpack/__tests__/__snapshots__/ForemanRhCloudHelpers.test.js.snap +0 -19
- data/webpack/__tests__/__snapshots__/ForemanRhCloudSelectors.test.js.snap +0 -25
- data/webpack/__tests__/__snapshots__/ForemanRhCloudTestHelpers.test.js.snap +0 -39
- data/webpack/common/Switcher/__tests__/__snapshots__/HelpLabel.test.js.snap +0 -16
- data/webpack/common/Switcher/__tests__/__snapshots__/SwitcherPF4.test.js.snap +0 -24
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 89c6b782cc34fb3ffc4f13ad66c435c5729028df995e7bdba1c15e668a72fe89
|
|
4
|
+
data.tar.gz: 356fb55567950b341b4509f6ee39e30b24127c695b3924765070167800595f44
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8bdb9ff78ed0950bd67f5bcc1483a0f2568af9a3462633ef6fc25d061bf942712d416d717f43e3dcef448dddb11cc6f7b9ad1fe62d6530ad2dbf44af3a3eb4a6
|
|
7
|
+
data.tar.gz: f55334cb175a624ae8aeb21242b609ce8af3c49061c7e09b460b46fef3d3239cab42232c0c52eb043ed345a661b331409545344f24e89e46e3fb9a782666e1bc
|
|
@@ -106,6 +106,7 @@ module ForemanInventoryUpload
|
|
|
106
106
|
|
|
107
107
|
def host_ips(host)
|
|
108
108
|
# Determines and returns the IP addresses associated with a host, applying obfuscation if enabled.
|
|
109
|
+
return {} if host.nil?
|
|
109
110
|
|
|
110
111
|
# If IP obfuscation is enabled for the host return a representation of obfuscated IP addresses.
|
|
111
112
|
return obfuscated_ips(host) if obfuscate_ips?(host)
|
|
@@ -155,10 +156,29 @@ module ForemanInventoryUpload
|
|
|
155
156
|
|
|
156
157
|
def hostname_match
|
|
157
158
|
bash_hostname = `uname -n`.chomp
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
159
|
+
foreman_host = ForemanRhCloud.foreman_host
|
|
160
|
+
|
|
161
|
+
# If bash hostname matches foreman_host, use fqdn
|
|
162
|
+
if foreman_host && bash_hostname == foreman_host.name
|
|
163
|
+
return fqdn(foreman_host)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# If no foreman_host, try foreman_host_name from Setting[:foreman_url]
|
|
167
|
+
unless foreman_host
|
|
168
|
+
foreman_hostname_from_setting = ForemanRhCloud.foreman_host_name
|
|
169
|
+
if foreman_hostname_from_setting
|
|
170
|
+
# Apply obfuscation if enabled
|
|
171
|
+
return obfuscate_fqdn(foreman_hostname_from_setting) if Setting[:obfuscate_inventory_hostnames]
|
|
172
|
+
|
|
173
|
+
return foreman_hostname_from_setting
|
|
174
|
+
end
|
|
175
|
+
# Otherwise fall through to bash_hostname below
|
|
176
|
+
# NOTE: Containerized foremanctl setups must configure Setting[:foreman_url]
|
|
177
|
+
# as bash hostname may not be available or meaningful in containers
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Fallback to bash hostname (with obfuscation if enabled)
|
|
181
|
+
if Setting[:obfuscate_inventory_hostnames]
|
|
162
182
|
obfuscate_fqdn(bash_hostname)
|
|
163
183
|
else
|
|
164
184
|
bash_hostname
|
|
@@ -166,6 +186,8 @@ module ForemanInventoryUpload
|
|
|
166
186
|
end
|
|
167
187
|
|
|
168
188
|
def bios_uuid(host)
|
|
189
|
+
return nil if host.nil?
|
|
190
|
+
|
|
169
191
|
value = fact_value(host, 'dmi::system::uuid') || ''
|
|
170
192
|
uuid_value(value)
|
|
171
193
|
end
|
|
@@ -96,7 +96,14 @@ module ForemanInventoryUpload
|
|
|
96
96
|
end
|
|
97
97
|
|
|
98
98
|
def self.inventory_self_url
|
|
99
|
-
|
|
99
|
+
host = ForemanRhCloud.foreman_host
|
|
100
|
+
hostname = host ? host.fqdn : ForemanRhCloud.foreman_host_name
|
|
101
|
+
if hostname.nil?
|
|
102
|
+
Rails.logger.warn("Cannot determine Foreman hostname for inventory sync. " \
|
|
103
|
+
"Please configure Setting[:foreman_url]. " \
|
|
104
|
+
"Containerized setups must explicitly set this.")
|
|
105
|
+
end
|
|
106
|
+
inventory_base_url + "?hostname_or_id=#{hostname}"
|
|
100
107
|
end
|
|
101
108
|
|
|
102
109
|
def self.host_by_id_url(host_uuid)
|
data/lib/foreman_rh_cloud.rb
CHANGED
|
@@ -84,23 +84,50 @@ module ForemanRhCloud
|
|
|
84
84
|
|
|
85
85
|
# For testing purposes we can override the default hostname with an environment variable SATELLITE_RH_CLOUD_FOREMAN_HOST
|
|
86
86
|
def self.foreman_host
|
|
87
|
-
@foreman_host
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
87
|
+
return @foreman_host if defined?(@foreman_host)
|
|
88
|
+
|
|
89
|
+
fullname = foreman_host_name
|
|
90
|
+
return @foreman_host = nil unless fullname
|
|
91
|
+
|
|
92
|
+
# Try fullname first
|
|
93
|
+
host = ::Host.unscoped.friendly.where(name: fullname).first
|
|
94
|
+
|
|
95
|
+
# If not found, try shortname
|
|
96
|
+
if host.nil?
|
|
92
97
|
shortname = /(?<shortname>[^\.]*)\.?.*/.match(fullname)[:shortname]
|
|
93
|
-
::Host.unscoped.friendly.
|
|
98
|
+
host = ::Host.unscoped.friendly.where(name: shortname).first
|
|
94
99
|
end
|
|
100
|
+
|
|
101
|
+
@foreman_host = host
|
|
95
102
|
end
|
|
96
103
|
|
|
97
104
|
def self.foreman_host_name
|
|
98
|
-
ENV['SATELLITE_RH_CLOUD_FOREMAN_HOST'] || marked_foreman_host&.name ||
|
|
105
|
+
ENV['SATELLITE_RH_CLOUD_FOREMAN_HOST'] || marked_foreman_host&.name || foreman_url_hostname
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def self.foreman_url_hostname
|
|
109
|
+
return nil unless Setting[:foreman_url]
|
|
110
|
+
|
|
111
|
+
begin
|
|
112
|
+
# Ensure setting is a string to avoid TypeError from URI.parse
|
|
113
|
+
url = Setting[:foreman_url].to_s
|
|
114
|
+
URI.parse(url).host
|
|
115
|
+
rescue URI::InvalidURIError, ArgumentError, TypeError => e
|
|
116
|
+
Rails.logger.warn("Invalid foreman_url setting: #{e.message}")
|
|
117
|
+
nil
|
|
118
|
+
end
|
|
99
119
|
end
|
|
100
120
|
|
|
101
121
|
def self.marked_foreman_host
|
|
102
|
-
|
|
103
|
-
|
|
122
|
+
# Find host with infrastructure_facet.foreman_instance = true
|
|
123
|
+
# Facets use a special mechanism in Foreman, so we query the facet table directly
|
|
124
|
+
return nil unless defined?(HostFacets::InfrastructureFacet)
|
|
125
|
+
|
|
126
|
+
facet = HostFacets::InfrastructureFacet.find_by(foreman_instance: true)
|
|
127
|
+
facet&.host
|
|
128
|
+
rescue ActiveRecord::StatementInvalid => e
|
|
129
|
+
# Table might not exist yet during migrations
|
|
130
|
+
Rails.logger.debug("Could not query marked foreman host: #{e.message}")
|
|
104
131
|
nil
|
|
105
132
|
end
|
|
106
133
|
|
|
@@ -13,7 +13,16 @@ module InsightsCloud
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def add_satellite_notifications
|
|
16
|
-
|
|
16
|
+
host = foreman_host
|
|
17
|
+
|
|
18
|
+
# Skip if no Foreman host record exists
|
|
19
|
+
unless host
|
|
20
|
+
logger.debug("Skipping Insights notifications: no Foreman host record found")
|
|
21
|
+
blueprint&.notifications&.destroy_all
|
|
22
|
+
return
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
hits_count = InsightsHit.where(host_id: host.id).count
|
|
17
26
|
|
|
18
27
|
# Remove stale notifications
|
|
19
28
|
blueprint.notifications.destroy_all
|
|
@@ -4,7 +4,14 @@ module InventorySync
|
|
|
4
4
|
set_callback :step, :around, :create_facets
|
|
5
5
|
|
|
6
6
|
def plan
|
|
7
|
-
|
|
7
|
+
host = ForemanRhCloud.foreman_host
|
|
8
|
+
|
|
9
|
+
if host.nil?
|
|
10
|
+
logger.warn("Skipping self-host inventory sync: no Foreman host record found.")
|
|
11
|
+
return
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
super(host.organization)
|
|
8
15
|
end
|
|
9
16
|
|
|
10
17
|
def create_facets
|
|
@@ -22,7 +29,10 @@ module InventorySync
|
|
|
22
29
|
private
|
|
23
30
|
|
|
24
31
|
def add_missing_insights_facet(uuids_hash)
|
|
25
|
-
|
|
32
|
+
host = ForemanRhCloud.foreman_host
|
|
33
|
+
return unless host # Guard against nil
|
|
34
|
+
|
|
35
|
+
facet = InsightsFacet.find_or_create_by(host_id: host.id) do |facet|
|
|
26
36
|
facet.uuid = uuids_hash.values.first
|
|
27
37
|
end
|
|
28
38
|
|
data/package.json
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'test_plugin_helper'
|
|
2
|
+
require 'foreman_tasks/test_helpers'
|
|
3
|
+
|
|
4
|
+
class InsightsGenerateNotificationsTest < ActiveSupport::TestCase
|
|
5
|
+
include Dynflow::Testing::Factories
|
|
6
|
+
|
|
7
|
+
setup do
|
|
8
|
+
User.current = User.find_by(login: 'secret_admin')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
test 'skips notifications when foreman_host is nil' do
|
|
12
|
+
ForemanRhCloud.stubs(:foreman_host).returns(nil)
|
|
13
|
+
|
|
14
|
+
# Ensure blueprint exists or create it
|
|
15
|
+
NotificationBlueprint.find_or_create_by(name: 'insights_satellite_hits') do |bp|
|
|
16
|
+
bp.message = 'Test message'
|
|
17
|
+
bp.level = 'info'
|
|
18
|
+
bp.expires_in = 7.days
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
plan = ForemanTasks.sync_task(InsightsCloud::Async::InsightsGenerateNotifications)
|
|
22
|
+
|
|
23
|
+
# Should not raise an error, task completes successfully
|
|
24
|
+
assert_includes ['success', 'stopped'], plan.state, "Task should complete without error"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -106,4 +106,13 @@ class InventorySelfHostSyncTest < ActiveSupport::TestCase
|
|
|
106
106
|
|
|
107
107
|
assert_equal @host1_inventory_id, @host1.insights.uuid
|
|
108
108
|
end
|
|
109
|
+
|
|
110
|
+
test 'skips sync when foreman_host is nil' do
|
|
111
|
+
ForemanRhCloud.stubs(:foreman_host).returns(nil)
|
|
112
|
+
|
|
113
|
+
plan = ForemanTasks.sync_task(InventorySync::Async::InventorySelfHostSync)
|
|
114
|
+
|
|
115
|
+
# Task should be stopped (not executed) when host is nil, not failed
|
|
116
|
+
assert_equal 'stopped', plan.state
|
|
117
|
+
end
|
|
109
118
|
end
|
|
@@ -2,8 +2,9 @@ require 'test_plugin_helper'
|
|
|
2
2
|
|
|
3
3
|
class ForemanRhCloudSelfHostTest < ActiveSupport::TestCase
|
|
4
4
|
setup do
|
|
5
|
-
# reset cached value
|
|
6
|
-
ForemanRhCloud.
|
|
5
|
+
# reset cached value - must remove the variable entirely, not just set to nil
|
|
6
|
+
ForemanRhCloud.remove_instance_variable(:@foreman_host) if ForemanRhCloud.instance_variable_defined?(:@foreman_host)
|
|
7
|
+
ENV.delete('SATELLITE_RH_CLOUD_FOREMAN_HOST')
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
test 'finds host by fullname' do
|
|
@@ -32,4 +33,51 @@ class ForemanRhCloudSelfHostTest < ActiveSupport::TestCase
|
|
|
32
33
|
|
|
33
34
|
assert_equal @host, actual
|
|
34
35
|
end
|
|
36
|
+
|
|
37
|
+
test 'returns nil when host does not exist' do
|
|
38
|
+
ForemanRhCloud.expects(:foreman_host_name).returns('nonexistent.example.com')
|
|
39
|
+
|
|
40
|
+
actual = ForemanRhCloud.foreman_host
|
|
41
|
+
|
|
42
|
+
assert_nil actual
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
test 'returns nil and does not query Host when foreman_host_name is nil' do
|
|
46
|
+
ForemanRhCloud.stubs(:foreman_host_name).returns(nil)
|
|
47
|
+
::Host.unscoped.friendly.expects(:where).never
|
|
48
|
+
|
|
49
|
+
assert_nil ForemanRhCloud.foreman_host
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
test 'caches nil value to avoid repeated lookups' do
|
|
53
|
+
ForemanRhCloud.expects(:foreman_host_name).once.returns('nonexistent.example.com')
|
|
54
|
+
|
|
55
|
+
2.times { ForemanRhCloud.foreman_host }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
test 'extracts hostname from foreman_url setting' do
|
|
59
|
+
Setting[:foreman_url] = 'https://satellite.example.com'
|
|
60
|
+
|
|
61
|
+
actual = ForemanRhCloud.foreman_url_hostname
|
|
62
|
+
|
|
63
|
+
assert_equal 'satellite.example.com', actual
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
test 'handles invalid foreman_url gracefully' do
|
|
67
|
+
# Stub Setting to return invalid URL without validation
|
|
68
|
+
Setting.stubs(:[]).with(:foreman_url).returns('not a valid url')
|
|
69
|
+
|
|
70
|
+
actual = ForemanRhCloud.foreman_url_hostname
|
|
71
|
+
|
|
72
|
+
assert_nil actual
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
test 'foreman_host_name uses foreman_url when marked_foreman_host is nil' do
|
|
76
|
+
ForemanRhCloud.expects(:marked_foreman_host).returns(nil)
|
|
77
|
+
ForemanRhCloud.expects(:foreman_url_hostname).returns('satellite.example.com')
|
|
78
|
+
|
|
79
|
+
actual = ForemanRhCloud.foreman_host_name
|
|
80
|
+
|
|
81
|
+
assert_equal 'satellite.example.com', actual
|
|
82
|
+
end
|
|
35
83
|
end
|
|
@@ -2,7 +2,8 @@ require 'test_plugin_helper'
|
|
|
2
2
|
|
|
3
3
|
class MetadataGeneratorTest < ActiveSupport::TestCase
|
|
4
4
|
setup do
|
|
5
|
-
|
|
5
|
+
# reset cached value - must remove the variable entirely, not just set to nil
|
|
6
|
+
ForemanRhCloud.remove_instance_variable(:@foreman_host) if ForemanRhCloud.instance_variable_defined?(:@foreman_host)
|
|
6
7
|
end
|
|
7
8
|
|
|
8
9
|
test 'generates an empty report' do
|
|
@@ -64,4 +65,26 @@ class MetadataGeneratorTest < ActiveSupport::TestCase
|
|
|
64
65
|
assert_not_nil(slice = slices['test_12345'])
|
|
65
66
|
assert_equal 3, slice['number_hosts']
|
|
66
67
|
end
|
|
68
|
+
|
|
69
|
+
test 'generates metadata when foreman_host is nil' do
|
|
70
|
+
ForemanRhCloud.stubs(:foreman_host).returns(nil)
|
|
71
|
+
ForemanRhCloud.stubs(:foreman_host_name).returns('satellite.example.com')
|
|
72
|
+
|
|
73
|
+
generator = ForemanInventoryUpload::Generators::Metadata.new
|
|
74
|
+
|
|
75
|
+
# Should not raise an error
|
|
76
|
+
json_str = nil
|
|
77
|
+
assert_nothing_raised do
|
|
78
|
+
json_str = generator.render do
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Verify hostname is from foreman_host_name
|
|
83
|
+
actual = JSON.parse(json_str.join("\n"))
|
|
84
|
+
assert_equal 'satellite.example.com', actual['reporting_host_name']
|
|
85
|
+
# Verify IP and BIOS UUID fields are nil when host is nil
|
|
86
|
+
# This is acceptable per SAT-25889 - cloud services don't rely on these fields
|
|
87
|
+
assert_nil actual['reporting_host_ips']
|
|
88
|
+
assert_nil actual['reporting_host_bios_uuid']
|
|
89
|
+
end
|
|
67
90
|
end
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
3
|
import EmptyResults from '../EmptyResults';
|
|
4
4
|
|
|
5
|
-
const fixtures = {
|
|
6
|
-
'render without Props': {},
|
|
7
|
-
/** fixtures, props for the component */
|
|
8
|
-
};
|
|
9
|
-
|
|
10
5
|
describe('EmptyResults', () => {
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
it('renders the empty results message', () => {
|
|
7
|
+
render(<EmptyResults />);
|
|
8
|
+
expect(
|
|
9
|
+
screen.getByText(
|
|
10
|
+
"Oops! Couldn't find organization that matches your query"
|
|
11
|
+
)
|
|
12
|
+
).toBeTruthy();
|
|
13
|
+
});
|
|
13
14
|
});
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
3
|
import EmptyState from '../EmptyState';
|
|
4
4
|
|
|
5
|
-
const fixtures = {
|
|
6
|
-
'render without Props': {},
|
|
7
|
-
/** fixtures, props for the component */
|
|
8
|
-
};
|
|
9
|
-
|
|
10
5
|
describe('EmptyState', () => {
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
it('renders fetching data message', () => {
|
|
7
|
+
render(<EmptyState />);
|
|
8
|
+
expect(
|
|
9
|
+
screen.getByText('Fetching data about your accounts')
|
|
10
|
+
).toBeTruthy();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('renders loading indicator', () => {
|
|
14
|
+
render(<EmptyState />);
|
|
15
|
+
expect(screen.getByText('Loading...')).toBeTruthy();
|
|
16
|
+
});
|
|
13
17
|
});
|
|
@@ -1,13 +1,24 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
3
|
import ErrorState from '../ErrorState';
|
|
4
4
|
|
|
5
|
-
const fixtures = {
|
|
6
|
-
'render without Props': {},
|
|
7
|
-
/** fixtures, props for the component */
|
|
8
|
-
};
|
|
9
|
-
|
|
10
5
|
describe('ErrorState', () => {
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
it('renders the error message heading', () => {
|
|
7
|
+
render(<ErrorState error="Something went wrong" />);
|
|
8
|
+
expect(
|
|
9
|
+
screen.getByText(
|
|
10
|
+
'Encountered an error while trying to access the server:'
|
|
11
|
+
)
|
|
12
|
+
).toBeTruthy();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('renders the error description', () => {
|
|
16
|
+
render(<ErrorState error="Connection refused" />);
|
|
17
|
+
expect(screen.getByText('Connection refused')).toBeTruthy();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('renders with empty error by default', () => {
|
|
21
|
+
const { container } = render(<ErrorState />);
|
|
22
|
+
expect(container.querySelector('.error_description')).toBeTruthy();
|
|
23
|
+
});
|
|
13
24
|
});
|
|
@@ -1,13 +1,36 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import { Accordion } from '@patternfly/react-core';
|
|
3
4
|
import ListItem from '../ListItem';
|
|
4
|
-
import { props } from '../ListItem.fixtures';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
jest.mock('../../../../Dashboard', () => () => null);
|
|
7
|
+
|
|
8
|
+
const renderListItem = props =>
|
|
9
|
+
render(
|
|
10
|
+
<Accordion>
|
|
11
|
+
<ListItem {...props} />
|
|
12
|
+
</Accordion>
|
|
13
|
+
);
|
|
9
14
|
|
|
10
15
|
describe('ListItem', () => {
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
const defaultProps = {
|
|
17
|
+
label: 'test-org',
|
|
18
|
+
account: {
|
|
19
|
+
generated_status: 'unknown',
|
|
20
|
+
uploaded_status: 'unknown',
|
|
21
|
+
id: 1,
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
it('renders the account label', () => {
|
|
26
|
+
renderListItem(defaultProps);
|
|
27
|
+
expect(screen.getByText('test-org')).toBeTruthy();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('renders Generated and Uploaded status labels', () => {
|
|
31
|
+
renderListItem(defaultProps);
|
|
32
|
+
expect(screen.getByText('Generated')).toBeTruthy();
|
|
33
|
+
expect(screen.getByText('Uploaded')).toBeTruthy();
|
|
34
|
+
});
|
|
35
|
+
|
|
13
36
|
});
|
|
@@ -1,14 +1,30 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
3
|
import ListItemStatus from '../ListItemStatus';
|
|
4
|
-
import { props } from '../ListItemStatus.fixtures';
|
|
5
|
-
|
|
6
|
-
const fixtures = {
|
|
7
|
-
'render without Props': {},
|
|
8
|
-
'render with Props': props,
|
|
9
|
-
};
|
|
10
4
|
|
|
11
5
|
describe('ListItemStatus', () => {
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
it('renders Generated and Uploaded labels', () => {
|
|
7
|
+
render(<ListItemStatus />);
|
|
8
|
+
expect(screen.getByText('Generated')).toBeTruthy();
|
|
9
|
+
expect(screen.getByText('Uploaded')).toBeTruthy();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('shows dash placeholders for unknown status', () => {
|
|
13
|
+
render(
|
|
14
|
+
<ListItemStatus
|
|
15
|
+
account={{ generated_status: 'unknown', uploaded_status: 'unknown' }}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
expect(screen.getAllByText('--')).toHaveLength(2);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('renders with provided account statuses', () => {
|
|
22
|
+
render(
|
|
23
|
+
<ListItemStatus
|
|
24
|
+
account={{ generated_status: 'success', uploaded_status: 'running' }}
|
|
25
|
+
/>
|
|
26
|
+
);
|
|
27
|
+
expect(screen.getByText('Generated')).toBeTruthy();
|
|
28
|
+
expect(screen.getByText('Uploaded')).toBeTruthy();
|
|
29
|
+
});
|
|
14
30
|
});
|
|
@@ -1,14 +1,38 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
3
|
import AccountList from '../AccountList';
|
|
4
|
-
import {
|
|
4
|
+
import { accounts } from '../AccountList.fixtures';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
};
|
|
6
|
+
jest.mock('../Components/ListItem', () => ({ label }) => (
|
|
7
|
+
<div>{label}</div>
|
|
8
|
+
));
|
|
10
9
|
|
|
11
10
|
describe('AccountList', () => {
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
it('renders account labels', () => {
|
|
12
|
+
render(<AccountList accounts={accounts} />);
|
|
13
|
+
Object.keys(accounts).forEach(label => {
|
|
14
|
+
expect(screen.getByText(label)).toBeTruthy();
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('shows empty results when filterTerm matches nothing', () => {
|
|
19
|
+
render(<AccountList accounts={accounts} filterTerm="not_matching_term" />);
|
|
20
|
+
expect(
|
|
21
|
+
screen.getByText(
|
|
22
|
+
"Oops! Couldn't find organization that matches your query"
|
|
23
|
+
)
|
|
24
|
+
).toBeTruthy();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('shows empty state when accounts are empty', () => {
|
|
28
|
+
render(<AccountList accounts={{}} />);
|
|
29
|
+
expect(
|
|
30
|
+
screen.getByText('Fetching data about your accounts')
|
|
31
|
+
).toBeTruthy();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('shows error state when error is present', () => {
|
|
35
|
+
render(<AccountList accounts={{}} error="Server error" />);
|
|
36
|
+
expect(screen.getByText('Server error')).toBeTruthy();
|
|
37
|
+
});
|
|
14
38
|
});
|