foreman_rh_cloud 0.9.8 → 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5d9bfa9bef95446c6a0bb20ca88c8e15c62f9972ff5dacdcf867010ea6aa9ecc
4
- data.tar.gz: 407db938baa5b0dd871af9a9e2d310cfce2a3b1037710b3cff0f9d58ed09b6e4
3
+ metadata.gz: '09f221b1f513c89b9aa56a858b920504335cc043e20fb9e97b7732ddd201b93d'
4
+ data.tar.gz: 6e8ec2007e1b38b6f2b086153196b22acb1ecd3ce682fad8981dfb0f2c21bc4c
5
5
  SHA512:
6
- metadata.gz: f31558e38ab7848a41283f7044dfc40410cd46e6c36a2a8e4ac7729171c920d65671e4933647454120b3e86bd4bdc61986b7d1d65d68e97f6b539f7989f39c9c
7
- data.tar.gz: 47d4ee1904f3055c73489444e699c3b4fe8f55cd5d8025ab33f30658b6de4aff861d061d69bb24ca129d1c067d5714356c9fe7fa6f76d5beff64a25da76a869c
6
+ metadata.gz: 4e96b8f5252b7714775587e47b0dec32e36db70c5d972edd7e3a104e916a59750189aca04a9a0bb87d1287d2ac647df39ae2dd05176c5fa025c2bd1cfe8e16f9
7
+ data.tar.gz: f19b66899b1bbfb6bdb4eca3b998fb11f92099b7cae551d4bfda6a8ac84d64720fbc0a6c6580a454f03beb67a1a606c2b877ce48dd7e864eae89ababb280def5
@@ -5,7 +5,7 @@ class Setting::RhCloud < Setting
5
5
 
6
6
  transaction do
7
7
  [
8
- set('allow_auto_inventory_upload', N_('Allow automatic upload of the host inventory to the Red Hat cloud'), true),
8
+ set('allow_auto_inventory_upload', N_('Allow automatic upload of the host inventory to the Red Hat cloud'), false),
9
9
  set('obfuscate_inventory_hostnames', N_('Obfuscate host names sent to Red Hat cloud'), false),
10
10
  set('rh_cloud_token', N_('Authentication token to Red Hat cloud services. Used to authenticate requests to cloud APIs'), 'DEFAULT', N_('Red Hat Cloud token'), nil, encrypted: true),
11
11
  ].each { |s| create! s.update(:category => 'Setting::RhCloud')}
@@ -1 +1,6 @@
1
- <%= mount_react_component('InsightsCloudSync', '#ForemanRhCloudReactRoot') %>
1
+ <%= mount_react_component(
2
+ 'InsightsCloudSync',
3
+ '#ForemanRhCloudReactRoot',
4
+ {
5
+ settingsUrl: settings_url(search: 'name = rh_cloud_token')
6
+ }.to_json) %>
@@ -36,6 +36,16 @@ module ForemanInventoryUpload
36
36
  @out << ',' unless last
37
37
  end
38
38
 
39
+ def string_array_value(name, value, last = false)
40
+ return if value.empty?
41
+
42
+ string_value = value.map { |v| stringify_value(v) }
43
+
44
+ array_field(name, last) do
45
+ raw(string_value.join(', '))
46
+ end
47
+ end
48
+
39
49
  def object_field(name, last = false, &block)
40
50
  @out << "\"#{name}\": "
41
51
  object(&block)
@@ -45,16 +45,8 @@ module ForemanInventoryUpload
45
45
  @stream.simple_field('satellite_id', host.subscription_facet&.uuid)
46
46
  @stream.simple_field('bios_uuid', fact_value(host, 'dmi::system::uuid'))
47
47
  @stream.simple_field('vm_uuid', fact_value(host, 'virt::uuid'))
48
- @stream.array_field('ip_addresses') do
49
- @stream.raw(host.interfaces.map do |nic|
50
- @stream.stringify_value(nic.ip) if nic.ip
51
- end.compact.join(', '))
52
- end
53
- @stream.array_field('mac_addresses') do
54
- @stream.raw(host.interfaces.map do |nic|
55
- @stream.stringify_value(nic.mac) if nic.mac
56
- end.compact.join(', '))
57
- end
48
+ report_ip_addresses(host)
49
+ report_mac_addresses(host)
58
50
  @stream.object_field('system_profile') do
59
51
  report_system_profile(host)
60
52
  end
@@ -161,6 +153,18 @@ module ForemanInventoryUpload
161
153
  @stream.simple_field('organization_id', host.organization_id, :last)
162
154
  end
163
155
 
156
+ def report_ip_addresses(host)
157
+ ip_addresses = host.interfaces.map { |nic| nic.ip }.compact
158
+
159
+ @stream.string_array_value('ip_addresses', ip_addresses)
160
+ end
161
+
162
+ def report_mac_addresses(host)
163
+ macs = host.interfaces.map { |nic| nic.mac }.compact
164
+
165
+ @stream.string_array_value('mac_addresses', macs)
166
+ end
167
+
164
168
  def os_release_value(name:, version:, codename:)
165
169
  "#{name} #{version} (#{codename})"
166
170
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanRhCloud
2
- VERSION = '0.9.8'.freeze
2
+ VERSION = '0.9.9'.freeze
3
3
  end
@@ -68,7 +68,7 @@ module InsightsCloud
68
68
  def replace_hits_data(hits)
69
69
  InsightsHit.transaction do
70
70
  InsightsHit.delete_all
71
- InsightsHit.create(hits.map { |hits_hash| to_model_hash(hits_hash) })
71
+ InsightsHit.create(hits.map { |hits_hash| to_model_hash(hits_hash) }.compact)
72
72
  # create new facets for hosts that are missing one
73
73
  hosts_with_existing_facets = InsightsFacet.where(host_id: @host_ids.values).pluck(:host_id)
74
74
  InsightsFacet.create((@host_ids.values - hosts_with_existing_facets).map { |id| {host_id: id} })
@@ -76,8 +76,12 @@ module InsightsCloud
76
76
  end
77
77
 
78
78
  def to_model_hash(hit_hash)
79
+ hit_host_id = host_id(hit_hash['hostname'])
80
+
81
+ return unless hit_host_id
82
+
79
83
  {
80
- host_id: host_id(hit_hash['hostname']),
84
+ host_id: hit_host_id,
81
85
  last_seen: Time.parse(hit_hash['last_seen']),
82
86
  publish_date: Time.parse(hit_hash['publish_date']),
83
87
  title: hit_hash['title'],
@@ -59,4 +59,34 @@ class InsightsFullSyncTest < ActiveJob::TestCase
59
59
  assert_equal 2, @host1.insights.hits.count
60
60
  assert_equal 1, @host2.insights.hits.count
61
61
  end
62
+
63
+ test 'Hits ignoring non-existent hosts' do
64
+ hits_json = <<-HITS_JSON
65
+ [
66
+ {
67
+ "hostname": "#{@host1.name}_non_existent",
68
+ "rhel_version": "7.5",
69
+ "uuid": "accdf444-5628-451d-bf3e-cf909ad72756",
70
+ "last_seen": "2019-11-22T08:41:42.447244Z",
71
+ "title": "New Ansible Engine packages are inaccessible when dedicated Ansible repo is not enabled",
72
+ "solution_url": "",
73
+ "total_risk": 2,
74
+ "likelihood": 2,
75
+ "publish_date": "2018-04-16T10:03:16Z",
76
+ "results_url": "https://cloud.redhat.com/insights/overview/stability/ansible_deprecated_repo%7CANSIBLE_DEPRECATED_REPO/accdf444-5628-451d-bf3e-cf909ad72756/"
77
+ }
78
+ ]
79
+ HITS_JSON
80
+ hits = JSON.parse(hits_json)
81
+
82
+ InsightsCloud::Async::InsightsFullSync.any_instance.expects(:query_insights_hits).returns(hits)
83
+
84
+ InsightsCloud::Async::InsightsFullSync.perform_now(@host1.organization)
85
+
86
+ @host1.reload
87
+ @host2.reload
88
+
89
+ assert_nil @host1.insights
90
+ assert_nil @host2.insights
91
+ end
62
92
  end
@@ -63,6 +63,25 @@ class ReportGeneratorTest < ActiveSupport::TestCase
63
63
 
64
64
  assert_equal 'slice_123', actual['report_slice_id']
65
65
  assert_not_nil(actual_host = actual['hosts'].first)
66
+ assert_nil actual_host['ip_addresses']
67
+ assert_nil actual_host['mac_addresses']
68
+ assert_equal @host.fqdn, actual_host['fqdn']
69
+ assert_equal '1234', actual_host['account']
70
+ assert_equal 1, generator.hosts_count
71
+ end
72
+
73
+ test 'generates ip_address and mac_address fields' do
74
+ @host.interfaces << FactoryBot.build(:nic_managed)
75
+ batch = Host.where(id: @host.id).in_batches.first
76
+ generator = create_generator(batch)
77
+
78
+ json_str = generator.render
79
+ actual = JSON.parse(json_str.join("\n"))
80
+
81
+ assert_equal 'slice_123', actual['report_slice_id']
82
+ assert_not_nil(actual_host = actual['hosts'].first)
83
+ assert_equal @host.interfaces.where.not(ip: nil).first.ip, actual_host['ip_addresses'].first
84
+ assert_equal @host.interfaces.where.not(mac: nil).first.mac, actual_host['mac_addresses'].first
66
85
  assert_equal @host.fqdn, actual_host['fqdn']
67
86
  assert_equal '1234', actual_host['account']
68
87
  assert_equal 1, generator.hosts_count
@@ -262,10 +281,17 @@ class ReportGeneratorTest < ActiveSupport::TestCase
262
281
  first_pool = @host.organization.pools.first
263
282
  second_pool = FactoryBot.create(:katello_pool, account_number: nil, cp_id: 2)
264
283
  new_org = FactoryBot.create(:organization, pools: [first_pool, second_pool])
265
- @host.organization = new_org
266
- @host.save!
267
284
 
268
- batch = Host.where(id: @host.id).in_batches.first
285
+ another_host = FactoryBot.create(
286
+ :host,
287
+ :with_subscription,
288
+ :with_content,
289
+ content_view: @host.content_view,
290
+ lifecycle_environment: @host.lifecycle_environment,
291
+ organization: new_org
292
+ )
293
+
294
+ batch = Host.where(id: another_host.id).in_batches.first
269
295
  generator = create_generator(batch)
270
296
 
271
297
  json_str = generator.render
@@ -10,12 +10,12 @@ export const PageDescription = () => (
10
10
  </p>
11
11
  <p>
12
12
  {__(
13
- 'In order to utilize these servies, you can set the auto upload in the settings to "ON".'
13
+ 'In order to utilize these services, you can set the auto upload in the settings to "ON".'
14
14
  )}
15
15
  </p>
16
16
  <p>
17
17
  {__(
18
- 'You can also trigger the upload manually by openning the relevant organization card, and clicking on the "Restart" button'
18
+ 'You can also trigger the upload manually by opening the relevant organization card, and clicking on the "Restart" button'
19
19
  )}
20
20
  </p>
21
21
  </div>
@@ -8,10 +8,10 @@ exports[`PageDescription rendering render without Props 1`] = `
8
8
  Red Hat Insights is a set of cloud services which provide unified subscription reporting, predictive analysis and remediation of issues through this Satellite instance.
9
9
  </p>
10
10
  <p>
11
- In order to utilize these servies, you can set the auto upload in the settings to "ON".
11
+ In order to utilize these services, you can set the auto upload in the settings to "ON".
12
12
  </p>
13
13
  <p>
14
- You can also trigger the upload manually by openning the relevant organization card, and clicking on the "Restart" button
14
+ You can also trigger the upload manually by opening the relevant organization card, and clicking on the "Restart" button
15
15
  </p>
16
16
  </div>
17
17
  `;
@@ -2,18 +2,44 @@ import React from 'react';
2
2
  import { IntlProvider } from 'react-intl';
3
3
  import PropTypes from 'prop-types';
4
4
  import { translate as __ } from 'foremanReact/common/I18n';
5
- import { Button } from 'patternfly-react';
5
+ import { Button, Icon } from 'patternfly-react';
6
6
  import { INSIGHTS_SYNC_PAGE_TITLE } from './InsightsCloudSyncConstants';
7
7
 
8
- const InsightsCloudSync = ({ syncInsights }) => {
8
+ const InsightsCloudSync = ({ data: { settingsUrl }, syncInsights }) => {
9
9
  document.title = INSIGHTS_SYNC_PAGE_TITLE;
10
10
  return (
11
11
  <IntlProvider locale={navigator.language}>
12
12
  <div className="insights-cloud-sync">
13
13
  <h1>{__('Red Hat Insights Sync')}</h1>
14
- <Button bsStyle="primary" onClick={syncInsights}>
15
- {__('Sync now')}
16
- </Button>
14
+ <p>
15
+ {__(`Insights synchronization process is used to provide Insights
16
+ recommendations output for hosts managed here`)}
17
+ </p>
18
+ <p>
19
+ {__(`1. Obtain an RHSM API token: `)}
20
+ <a
21
+ href="https://access.redhat.com/management/api"
22
+ target="_blank"
23
+ rel="noopener noreferrer"
24
+ >
25
+ access.redhat.com <Icon name="external-link" />
26
+ </a>
27
+ <br />
28
+ {__("2. Copy the token to 'Red Hat Cloud token' setting: ")}
29
+ <a href={settingsUrl} target="_blank" rel="noopener noreferrer">
30
+ {__('Red Hat Cloud token ')}
31
+ <Icon name="external-link" />
32
+ </a>
33
+ <br />
34
+ {__(
35
+ '3. Now you can syncronize recommendations manually using the "Sync now" button.'
36
+ )}
37
+ </p>
38
+ <div>
39
+ <Button bsStyle="primary" onClick={syncInsights}>
40
+ {__('Sync now')}
41
+ </Button>
42
+ </div>
17
43
  </div>
18
44
  </IntlProvider>
19
45
  );
@@ -21,6 +47,9 @@ const InsightsCloudSync = ({ syncInsights }) => {
21
47
 
22
48
  InsightsCloudSync.propTypes = {
23
49
  syncInsights: PropTypes.func.isRequired,
50
+ data: PropTypes.shape({
51
+ settingsUrl: PropTypes.string.isRequired,
52
+ }).isRequired,
24
53
  };
25
54
 
26
55
  export default InsightsCloudSync;
@@ -6,6 +6,9 @@ import InsightsCloudSync from './InsightsCloudSync';
6
6
  const fixtures = {
7
7
  render: {
8
8
  syncInsights: noop,
9
+ data: {
10
+ settingsUrl: 'www.example.com/settings',
11
+ },
9
12
  },
10
13
  };
11
14
 
@@ -10,16 +10,51 @@ exports[`InsightsCloudSync render 1`] = `
10
10
  <h1>
11
11
  Red Hat Insights Sync
12
12
  </h1>
13
- <Button
14
- active={false}
15
- block={false}
16
- bsClass="btn"
17
- bsStyle="primary"
18
- disabled={false}
19
- onClick={[Function]}
20
- >
21
- Sync now
22
- </Button>
13
+ <p>
14
+ Insights synchronization process is used to provide Insights
15
+ recommendations output for hosts managed here
16
+ </p>
17
+ <p>
18
+ 1. Obtain an RHSM API token:
19
+ <a
20
+ href="https://access.redhat.com/management/api"
21
+ rel="noopener noreferrer"
22
+ target="_blank"
23
+ >
24
+ access.redhat.com
25
+ <Icon
26
+ name="external-link"
27
+ type="fa"
28
+ />
29
+ </a>
30
+ <br />
31
+ 2. Copy the token to 'Red Hat Cloud token' setting:
32
+ <a
33
+ href="www.example.com/settings"
34
+ rel="noopener noreferrer"
35
+ target="_blank"
36
+ >
37
+ Red Hat Cloud token
38
+ <Icon
39
+ name="external-link"
40
+ type="fa"
41
+ />
42
+ </a>
43
+ <br />
44
+ 3. Now you can syncronize recommendations manually using the "Sync now" button.
45
+ </p>
46
+ <div>
47
+ <Button
48
+ active={false}
49
+ block={false}
50
+ bsClass="btn"
51
+ bsStyle="primary"
52
+ disabled={false}
53
+ onClick={[Function]}
54
+ >
55
+ Sync now
56
+ </Button>
57
+ </div>
23
58
  </div>
24
59
  </IntlProvider>
25
60
  `;
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_rh_cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.8
4
+ version: 0.9.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Foreman Red Hat Cloud team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-01 00:00:00.000000000 Z
11
+ date: 2020-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: katello