foreman_inventory_upload 0.0.1.dev1

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.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +619 -0
  3. data/README.md +38 -0
  4. data/Rakefile +47 -0
  5. data/app/controllers/foreman_inventory_upload/react_controller.rb +7 -0
  6. data/app/controllers/foreman_inventory_upload/reports_controller.rb +23 -0
  7. data/app/controllers/foreman_inventory_upload/statuses_controller.rb +41 -0
  8. data/app/controllers/foreman_inventory_upload/uploads_controller.rb +31 -0
  9. data/app/helpers/foreman_inventory_upload_helper.rb +13 -0
  10. data/app/views/dashboard/_inventory_upload_widget.html.erb +2 -0
  11. data/app/views/foreman_inventory_upload/layouts/react.html.erb +16 -0
  12. data/app/views/scripts/uploader.sh.erb +31 -0
  13. data/config/routes.rb +10 -0
  14. data/lib/foreman_inventory_upload/async/generate_report_job.rb +29 -0
  15. data/lib/foreman_inventory_upload/async/progress_output.rb +61 -0
  16. data/lib/foreman_inventory_upload/async/queue_for_upload_job.rb +52 -0
  17. data/lib/foreman_inventory_upload/async/shell_process.rb +35 -0
  18. data/lib/foreman_inventory_upload/async/upload_report_job.rb +40 -0
  19. data/lib/foreman_inventory_upload/engine.rb +52 -0
  20. data/lib/foreman_inventory_upload/generators/archived_report.rb +53 -0
  21. data/lib/foreman_inventory_upload/generators/json_stream.rb +55 -0
  22. data/lib/foreman_inventory_upload/generators/metadata.rb +36 -0
  23. data/lib/foreman_inventory_upload/generators/queries.rb +52 -0
  24. data/lib/foreman_inventory_upload/generators/slice.rb +117 -0
  25. data/lib/foreman_inventory_upload/version.rb +3 -0
  26. data/lib/foreman_inventory_upload.rb +48 -0
  27. data/lib/tasks/foreman_inventory_upload_tasks.rake +37 -0
  28. data/lib/tasks/generator.rake +15 -0
  29. data/locale/Makefile +60 -0
  30. data/locale/en/foreman_yupana.po +19 -0
  31. data/locale/foreman_yupana.pot +19 -0
  32. data/locale/gemspec.rb +2 -0
  33. data/test/controllers/reports_controller_test.rb +21 -0
  34. data/test/controllers/statuses_controller_test.rb +26 -0
  35. data/test/controllers/uploads_controller_test.rb +21 -0
  36. data/test/factories/inventory_upload_factories.rb +88 -0
  37. data/test/test_plugin_helper.rb +26 -0
  38. data/test/unit/archived_report_generator_test.rb +61 -0
  39. data/test/unit/metadata_generator_test.rb +40 -0
  40. data/test/unit/shell_process_job_test.rb +27 -0
  41. data/test/unit/slice_generator_test.rb +60 -0
  42. metadata +149 -0
@@ -0,0 +1,52 @@
1
+ module ForemanInventoryUpload
2
+ module Generators
3
+ class Queries
4
+ def self.fact_names
5
+ @fact_names ||= Hash[
6
+ Katello::RhsmFactName.where(name:
7
+ [
8
+ 'dmi::system::uuid',
9
+ 'virt::uuid',
10
+ 'cpu::cpu(s)',
11
+ 'cpu::cpu_socket(s)',
12
+ 'cpu::core(s)_per_socket',
13
+ 'memory::memtotal',
14
+ 'dmi::bios::vendor',
15
+ 'dmi::bios::version',
16
+ 'dmi::bios::relase_date',
17
+ 'distribution::name',
18
+ 'uname::release',
19
+ 'lscpu::flags'
20
+ ]).pluck(:name, :id)
21
+ ]
22
+ end
23
+
24
+ def self.for_slice(base)
25
+ fact_values = FactValue.where(fact_name_id: fact_names.values)
26
+ base
27
+ .joins(:subscription_facet)
28
+ .eager_load(:fact_values)
29
+ .preload(
30
+ :interfaces,
31
+ :installed_packages,
32
+ :content_facet,
33
+ :host_statuses,
34
+ subscription_facet: %i[pools installed_products]
35
+ )
36
+ .merge(fact_values)
37
+ end
38
+
39
+ def self.for_report(portal_user)
40
+ org_ids = Organization
41
+ .joins(:telemetry_configuration)
42
+ .where(
43
+ redhat_access_telemetry_configurations: {
44
+ portal_user: portal_user,
45
+ enable_telemetry: true
46
+ }
47
+ ).pluck(:id)
48
+ for_slice(Host.where(organization_id: org_ids)).in_batches(of: 1_000)
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,117 @@
1
+ module ForemanInventoryUpload
2
+ module Generators
3
+ class Slice
4
+ attr_accessor :slice_id
5
+
6
+ def initialize(hosts, output = [], slice_id = Foreman.uuid)
7
+ @stream = JsonStream.new(output)
8
+ @hosts = hosts
9
+ @slice_id = slice_id
10
+ end
11
+
12
+ def render
13
+ report_slice(@hosts)
14
+ @stream.out
15
+ end
16
+
17
+ private
18
+
19
+ def report_slice(hosts_batch)
20
+ @stream.object do
21
+ @stream.simple_field('report_slice_id', @slice_id)
22
+ @stream.array_field('hosts', :last) do
23
+ first = true
24
+ hosts_batch.each do |host|
25
+ @stream.comma unless first
26
+ first = false
27
+ report_host(host)
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ def report_host(host)
34
+ @stream.object do
35
+ @stream.simple_field('display_name', host.name)
36
+ @stream.simple_field('fqdn', host.fqdn)
37
+ @stream.simple_field('account', host.subscription_facet.pools.first.account_number.to_s)
38
+ @stream.simple_field('subscription_manager_id', host.subscription_facet.uuid)
39
+ @stream.simple_field('satellite_id', host.subscription_facet.uuid)
40
+ @stream.simple_field('bios_uuid', fact_value(host, 'dmi::system::uuid'))
41
+ @stream.simple_field('vm_uuid', fact_value(host, 'virt::uuid'))
42
+ @stream.array_field('ip_addresses') do
43
+ @stream.raw(host.interfaces.map do |nic|
44
+ @stream.stringify_value(nic.ip) if nic.ip
45
+ end.compact.join(', '))
46
+ end
47
+ @stream.array_field('mac_addresses') do
48
+ @stream.raw(host.interfaces.map do |nic|
49
+ @stream.stringify_value(nic.mac) if nic.mac
50
+ end.compact.join(', '))
51
+ end
52
+ @stream.object_field('system_profile', :last) do
53
+ report_system_profile(host)
54
+ end
55
+ end
56
+ end
57
+
58
+ def report_system_profile(host)
59
+ @stream.simple_field('number_of_cpus', fact_value(host, 'cpu::cpu(s)').to_i)
60
+ @stream.simple_field('number_of_sockets', fact_value(host, 'cpu::cpu_socket(s)').to_i)
61
+ @stream.simple_field('cores_per_socket', fact_value(host, 'cpu::core(s)_per_socket').to_i)
62
+ @stream.simple_field('system_memory_bytes', fact_value(host, 'memory::memtotal').to_i)
63
+ @stream.array_field('network_interfaces') do
64
+ @stream.raw(host.interfaces.map do |nic|
65
+ {
66
+ 'ipv4_addresses': [nic.ip].compact,
67
+ 'ipv6_addresses': [nic.ip6].compact,
68
+ 'mtu': nic.mtu,
69
+ 'mac_address': nic.mac,
70
+ 'name': nic.identifier
71
+ }.compact.to_json
72
+ end.join(', '))
73
+ end
74
+ @stream.simple_field('bios_vendor', fact_value(host, 'dmi::bios::vendor'))
75
+ @stream.simple_field('bios_version', fact_value(host, 'dmi::bios::version'))
76
+ @stream.simple_field('bios_release_date', fact_value(host, 'dmi::bios::relase_date'))
77
+ if (cpu_flags = fact_value(host, 'lscpu::flags'))
78
+ @stream.array_field('cpu_flags') do
79
+ @stream.raw(cpu_flags.split.map do |flag|
80
+ @stream.stringify_value(flag)
81
+ end.join(', '))
82
+ end
83
+ end
84
+ @stream.simple_field('os_release', fact_value(host, 'distribution::name'))
85
+ @stream.simple_field('os_kernel_version', fact_value(host, 'uname::release'))
86
+ @stream.simple_field('arch', host.architecture&.name)
87
+ @stream.simple_field('subscription_status', host.subscription_status_label)
88
+ @stream.simple_field('katello_agent_running', host.content_facet&.katello_agent_installed?)
89
+ @stream.simple_field('satellite_managed', true)
90
+ unless (installed_products = host.subscription_facet&.installed_products).empty?
91
+ @stream.array_field('installed_products') do
92
+ @stream.raw(installed_products.map do |product|
93
+ {
94
+ 'name': product.name,
95
+ 'id': product.cp_product_id
96
+ }.to_json
97
+ end.join(', '))
98
+ end
99
+ end
100
+ @stream.array_field('installed_packages', :last) do
101
+ first = true
102
+ host.installed_packages.each do |package|
103
+ @stream.raw("#{first ? '' : ', '}#{@stream.stringify_value(package.nvra)}")
104
+ first = false
105
+ end
106
+ end
107
+ end
108
+
109
+ def fact_value(host, fact_name)
110
+ value_record = host.fact_values.find do |fact_value|
111
+ fact_value.fact_name_id == ForemanInventoryUpload::Generators::Queries.fact_names[fact_name]
112
+ end
113
+ value_record&.value
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,3 @@
1
+ module ForemanInventoryUpload
2
+ VERSION = '0.0.1.dev1'.freeze
3
+ end
@@ -0,0 +1,48 @@
1
+ require 'foreman_inventory_upload/engine'
2
+
3
+ module ForemanInventoryUpload
4
+ def self.base_folder
5
+ # in production setup, where selinux is enabled, we only have rights to
6
+ # create folders under /ver/lib/foreman. If the folder does not exist, it's
7
+ # a dev setup, where we can use our current root
8
+ @base_folder ||= File.join(
9
+ Dir.glob('/var/lib/foreman').first || Dir.getwd,
10
+ 'red_hat_inventory/'
11
+ )
12
+ end
13
+
14
+ def self.uploads_folder(group)
15
+ @uploads_folders ||= {}
16
+ cache = @uploads_folders[group]
17
+ return cache if cache
18
+
19
+ @uploads_folders[group] = ensure_folder(
20
+ File.join(
21
+ ForemanInventoryUpload.base_folder,
22
+ 'uploads/',
23
+ "#{group}/"
24
+ )
25
+ )
26
+ end
27
+
28
+ def self.outputs_folder
29
+ @outputs_folder ||= ensure_folder(File.join(ForemanInventoryUpload.base_folder, 'outputs/'))
30
+ end
31
+
32
+ def self.upload_script_file
33
+ 'uploader.sh'
34
+ end
35
+
36
+ def self.facts_archive_name
37
+ 'hosts_report.tar.gz'
38
+ end
39
+
40
+ def self.upload_url
41
+ 'https://ci.cloud.paas.psi.redhat.com/api/ingress/v1/upload'
42
+ end
43
+
44
+ def self.ensure_folder(folder)
45
+ FileUtils.mkdir_p(folder)
46
+ folder
47
+ end
48
+ end
@@ -0,0 +1,37 @@
1
+ require 'rake/testtask'
2
+
3
+ # Tests
4
+ namespace :test do
5
+ desc 'Test ForemanInventoryUpload'
6
+ Rake::TestTask.new(:foreman_inventory_upload) do |t|
7
+ test_dir = File.join(File.dirname(__FILE__), '../..', 'test')
8
+ t.libs << ['test', test_dir]
9
+ t.pattern = "#{test_dir}/**/*_test.rb"
10
+ t.verbose = true
11
+ t.warning = false
12
+ end
13
+ end
14
+
15
+ namespace :foreman_inventory_upload do
16
+ task :rubocop do
17
+ begin
18
+ require 'rubocop/rake_task'
19
+ RuboCop::RakeTask.new(:rubocop_foreman_inventory_upload) do |task|
20
+ task.patterns = ["#{ForemanInventoryUpload::Engine.root}/app/**/*.rb",
21
+ "#{ForemanInventoryUpload::Engine.root}/lib/**/*.rb",
22
+ "#{ForemanInventoryUpload::Engine.root}/test/**/*.rb"]
23
+ end
24
+ rescue
25
+ puts 'Rubocop not loaded.'
26
+ end
27
+
28
+ Rake::Task['rubocop_foreman_inventory_upload'].invoke
29
+ end
30
+ end
31
+
32
+ Rake::Task[:test].enhance ['test:foreman_inventory_upload']
33
+
34
+ load 'tasks/jenkins.rake'
35
+ if Rake::Task.task_defined?(:'jenkins:unit')
36
+ Rake::Task['jenkins:unit'].enhance ['test:foreman_inventory_upload', 'foreman_inventory_upload:rubocop']
37
+ end
@@ -0,0 +1,15 @@
1
+ require 'tempfile'
2
+
3
+ namespace :foreman_inventory_upload do
4
+ namespace :report do
5
+ desc 'Generate inventory report to be sent to Red Hat cloud'
6
+ task generate: :environment do
7
+ target = ENV['target'] || ForemanInventoryUpload.facts_archive_name
8
+ portal_user = ENV['portal_user'] || 'anonymous'
9
+
10
+ archived_report_generator = ForemanInventoryUpload::Generators::ArchivedReport.new(target, Logger.new(STDOUT))
11
+ archived_report_generator.render(portal_user)
12
+ puts "Successfully generated #{target} for #{portal_user}"
13
+ end
14
+ end
15
+ end
data/locale/Makefile ADDED
@@ -0,0 +1,60 @@
1
+ #
2
+ # Makefile for PO merging and MO generation. More info in the README.
3
+ #
4
+ # make all-mo (default) - generate MO files
5
+ # make check - check translations using translate-tool
6
+ # make tx-update - download and merge translations from Transifex
7
+ # make clean - clean everything
8
+ #
9
+ DOMAIN = foreman_yupana
10
+ VERSION = $(shell ruby -e 'require "rubygems";spec = Gem::Specification::load(Dir.glob("../*.gemspec")[0]);puts spec.version')
11
+ POTFILE = $(DOMAIN).pot
12
+ MOFILE = $(DOMAIN).mo
13
+ POFILES = $(shell find . -name '$(DOMAIN).po')
14
+ MOFILES = $(patsubst %.po,%.mo,$(POFILES))
15
+ POXFILES = $(patsubst %.po,%.pox,$(POFILES))
16
+ EDITFILES = $(patsubst %.po,%.edit.po,$(POFILES))
17
+
18
+ %.mo: %.po
19
+ mkdir -p $(shell dirname $@)/LC_MESSAGES
20
+ msgfmt -o $(shell dirname $@)/LC_MESSAGES/$(MOFILE) $<
21
+
22
+ # Generate MO files from PO files
23
+ all-mo: $(MOFILES)
24
+
25
+ # Check for malformed strings
26
+ %.pox: %.po
27
+ msgfmt -c $<
28
+ pofilter --nofuzzy -t variables -t blank -t urls -t emails -t long -t newlines \
29
+ -t endwhitespace -t endpunc -t puncspacing -t options -t printf -t validchars --gnome $< > $@
30
+ cat $@
31
+ ! grep -q msgid $@
32
+
33
+ %.edit.po:
34
+ touch $@
35
+
36
+ check: $(POXFILES)
37
+
38
+ # Unify duplicate translations
39
+ uniq-po:
40
+ for f in $(shell find ./ -name "*.po") ; do \
41
+ msguniq $$f -o $$f ; \
42
+ done
43
+
44
+ tx-pull: $(EDITFILES)
45
+ tx pull -f
46
+ for f in $(EDITFILES) ; do \
47
+ sed -i 's/^\("Project-Id-Version: \).*$$/\1$(DOMAIN) $(VERSION)\\n"/' $$f; \
48
+ done
49
+
50
+ tx-update: tx-pull
51
+ @echo
52
+ @echo Run rake plugin:gettext[$(DOMAIN)] from the Foreman installation, then make -C locale mo-files to finish
53
+ @echo
54
+
55
+ mo-files: $(MOFILES)
56
+ git add $(POFILES) $(POTFILE) ../locale/*/LC_MESSAGES
57
+ git commit -m "i18n - pulling from tx"
58
+ @echo
59
+ @echo Changes commited!
60
+ @echo
@@ -0,0 +1,19 @@
1
+ # foreman_yupana
2
+ #
3
+ # This file is distributed under the same license as foreman_yupana.
4
+ #
5
+ #, fuzzy
6
+ msgid ""
7
+ msgstr ""
8
+ "Project-Id-Version: version 0.0.1\n"
9
+ "Report-Msgid-Bugs-To: \n"
10
+ "POT-Creation-Date: 2014-08-20 08:46+0100\n"
11
+ "PO-Revision-Date: 2014-08-20 08:54+0100\n"
12
+ "Last-Translator: Foreman Team <foreman-dev@googlegroups.com>\n"
13
+ "Language-Team: Foreman Team <foreman-dev@googlegroups.com>\n"
14
+ "Language: \n"
15
+ "MIME-Version: 1.0\n"
16
+ "Content-Type: text/plain; charset=UTF-8\n"
17
+ "Content-Transfer-Encoding: 8bit\n"
18
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
19
+
@@ -0,0 +1,19 @@
1
+ # foreman_yupana
2
+ #
3
+ # This file is distributed under the same license as foreman_yupana.
4
+ #
5
+ #, fuzzy
6
+ msgid ""
7
+ msgstr ""
8
+ "Project-Id-Version: version 0.0.1\n"
9
+ "Report-Msgid-Bugs-To: \n"
10
+ "POT-Creation-Date: 2014-08-20 08:46+0100\n"
11
+ "PO-Revision-Date: 2014-08-20 08:46+0100\n"
12
+ "Last-Translator: Foreman Team <foreman-dev@googlegroups.com>\n"
13
+ "Language-Team: Foreman Team <foreman-dev@googlegroups.com>\n"
14
+ "Language: \n"
15
+ "MIME-Version: 1.0\n"
16
+ "Content-Type: text/plain; charset=UTF-8\n"
17
+ "Content-Transfer-Encoding: 8bit\n"
18
+ "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
19
+
data/locale/gemspec.rb ADDED
@@ -0,0 +1,2 @@
1
+ # Matches foreman_yupana.gemspec
2
+ _('TODO: Description of ForemanYupana.')
@@ -0,0 +1,21 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class ReportsControllerTest < ActionController::TestCase
4
+ tests ForemanInventoryUpload::ReportsController
5
+
6
+ test 'Returns latest report generation status' do
7
+ progress_output = mock('progress_output')
8
+ test_portal_user = 'test_portal_user'
9
+ ForemanInventoryUpload::Async::ProgressOutput
10
+ .expects(:get)
11
+ .with(ForemanInventoryUpload::Async::GenerateReportJob.output_label(test_portal_user))
12
+ .returns(progress_output)
13
+ progress_output.expects(:full_output).returns('test output')
14
+
15
+ get :last, params: { portal_user: test_portal_user }, session: set_session_user
16
+
17
+ assert_response :success
18
+ actual = JSON.parse(response.body)
19
+ assert_equal 'test output', actual['output']
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class StatusesControllerTest < ActionController::TestCase
4
+ tests ForemanInventoryUpload::StatusesController
5
+
6
+ include FolderIsolation
7
+
8
+ test 'Returns statuses for each process type' do
9
+ configuration = RedhatAccess::TelemetryConfiguration.new(enable_telemetry: true, portal_user: 'test')
10
+ configuration.save!
11
+
12
+ generate_label = ForemanInventoryUpload::Async::GenerateReportJob.output_label('test')
13
+ generate_output = ForemanInventoryUpload::Async::ProgressOutput.register(generate_label)
14
+ generate_output.status = 'generate_status_test'
15
+ upload_label = ForemanInventoryUpload::Async::UploadReportJob.output_label('test')
16
+ upload_output = ForemanInventoryUpload::Async::ProgressOutput.register(upload_label)
17
+ upload_output.status = 'upload_status_test'
18
+
19
+ get :index, session: set_session_user
20
+
21
+ assert_response :success
22
+ actual = JSON.parse(response.body)['statuses']['test']
23
+ assert_equal 'generate_status_test', actual['generate_report_status']
24
+ assert_equal 'upload_status_test', actual['upload_report_status']
25
+ end
26
+ end
@@ -0,0 +1,21 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class UploadsControllerTest < ActionController::TestCase
4
+ tests ForemanInventoryUpload::UploadsController
5
+
6
+ test 'Returns latest upload status' do
7
+ progress_output = mock('progress_output')
8
+ test_portal_user = 'test_portal_user'
9
+ ForemanInventoryUpload::Async::ProgressOutput
10
+ .expects(:get)
11
+ .with(ForemanInventoryUpload::Async::UploadReportJob.output_label(test_portal_user))
12
+ .returns(progress_output)
13
+ progress_output.expects(:full_output).returns('test output')
14
+
15
+ get :last, params: { portal_user: test_portal_user }, session: set_session_user
16
+
17
+ assert_response :success
18
+ actual = JSON.parse(response.body)
19
+ assert_equal 'test output', actual['output']
20
+ end
21
+ end
@@ -0,0 +1,88 @@
1
+ # redefine katello factories, as long as katello is not compatible with dynamic properties
2
+ FactoryBot.define do
3
+ factory :katello_organization, :class => "Organization" do
4
+ type {"Organization"}
5
+ sequence(:name) { |n| "Organization#{n}" }
6
+ sequence(:label) { |n| "org#{n}" }
7
+ sequence(:id) { |n| n }
8
+
9
+ trait :acme_corporation do
10
+ name {"ACME_Corporation"}
11
+ type {"Organization"}
12
+ description {"This is the first Organization."}
13
+ label {"acme_corporation_label"}
14
+ end
15
+
16
+ trait :with_library do
17
+ association :library, :factory => :katello_library
18
+ end
19
+
20
+ factory :acme_corporation, :traits => [:acme_corporation]
21
+ end
22
+ end
23
+
24
+ FactoryBot.define do
25
+ factory :katello_content_view, :class => Katello::ContentView do
26
+ sequence(:name) { |n| "Database#{n}" }
27
+ description {"This content view is for database content"}
28
+ association :organization, :factory => :katello_organization
29
+
30
+ trait :composite do
31
+ composite {true}
32
+ end
33
+ end
34
+ end
35
+
36
+ FactoryBot.define do
37
+ factory :katello_k_t_environment, :aliases => [:katello_environment], :class => Katello::KTEnvironment do
38
+ sequence(:name) { |n| "Environment#{n}" }
39
+ sequence(:label) { |n| "environment#{n}" }
40
+ association :organization, :factory => :katello_organization
41
+ end
42
+ end
43
+
44
+ FactoryBot.define do
45
+ factory :katello_content_facets, :aliases => [:content_facet], :class => ::Katello::Host::ContentFacet do
46
+ sequence(:uuid) { |n| "uuid-#{n}" }
47
+ end
48
+ end
49
+
50
+ FactoryBot.define do
51
+ factory :katello_subscription_facets, :aliases => [:subscription_facet], :class => ::Katello::Host::SubscriptionFacet do
52
+ sequence(:uuid) { |n| "uuid-#{n}-#{rand(500)}" }
53
+ facts { {'memory.memtotal' => "12 GB"} }
54
+ end
55
+ end
56
+
57
+ FactoryBot.define do
58
+ factory :katello_pool, :class => Katello::Pool do
59
+ active {true}
60
+ end_date {Date.today + 1.year}
61
+ end
62
+ end
63
+
64
+ FactoryBot.modify do
65
+ factory :host do
66
+ transient do
67
+ content_view {nil}
68
+ lifecycle_environment {nil}
69
+ content_source {nil}
70
+ end
71
+
72
+ trait :with_content do
73
+ association :content_facet, :factory => :content_facet, :strategy => :build
74
+
75
+ after(:build) do |host, evaluator|
76
+ if host.content_facet
77
+ host.content_facet.content_view = evaluator.content_view if evaluator.content_view
78
+ host.content_facet.lifecycle_environment = evaluator.lifecycle_environment if evaluator.lifecycle_environment
79
+ host.content_facet.content_source = evaluator.content_source if evaluator.content_source
80
+ end
81
+ end
82
+ end
83
+
84
+ trait :with_subscription do
85
+ association :subscription_facet, :factory => :subscription_facet, :strategy => :build
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,26 @@
1
+ # This calls the main test_helper in Foreman-core
2
+ require 'test_helper'
3
+
4
+ # Add plugin to FactoryBot's paths
5
+ FactoryBot.definition_file_paths << File.join(File.dirname(__FILE__), 'factories')
6
+ # FactoryBot.definition_file_paths << "#{Katello::Engine.root}/test/factories"
7
+ FactoryBot.reload
8
+
9
+ module FolderIsolation
10
+ extend ActiveSupport::Concern
11
+
12
+ included do
13
+ setup do
14
+ @tmpdir = Dir.mktmpdir(self.class.name.underscore)
15
+
16
+ ForemanInventoryUpload.stubs(:base_folder).returns(@tmpdir)
17
+ ForemanInventoryUpload.instance_variable_set(:@outputs_folder, nil)
18
+ ForemanInventoryUpload.instance_variable_set(:@uploads_folders, nil)
19
+ end
20
+
21
+ teardown do
22
+ FileUtils.remove_entry @tmpdir
23
+ ForemanInventoryUpload.unstub(:base_folder)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,61 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class ArchivedReportGeneratorTest < ActiveSupport::TestCase
4
+ setup do
5
+ User.current = User.find_by(login: 'secret_admin')
6
+
7
+ env = FactoryBot.create(:katello_k_t_environment)
8
+ cv = env.content_views << FactoryBot.create(:katello_content_view, organization: env.organization)
9
+
10
+ @host = FactoryBot.create(
11
+ :host,
12
+ :with_subscription,
13
+ :with_content,
14
+ content_view: cv.first,
15
+ lifecycle_environment: env,
16
+ organization: env.organization
17
+ )
18
+
19
+ @host.subscription_facet.pools << FactoryBot.create(:katello_pool, account_number: '1234', cp_id: 1)
20
+ end
21
+
22
+ def interesting_facts
23
+ [
24
+ 'dmi::system::uuid',
25
+ 'virt::uuid',
26
+ 'cpu::cpu(s)',
27
+ 'cpu::cpu_socket(s)',
28
+ 'cpu::core(s)_per_socket',
29
+ 'memory::memtotal',
30
+ 'dmi::bios::vendor',
31
+ 'dmi::bios::version',
32
+ 'dmi::bios::relase_date',
33
+ 'distribution::name',
34
+ 'uname::release',
35
+ 'lscpu::flags'
36
+ ]
37
+ end
38
+
39
+ def fact_names
40
+ @fact_names ||= Hash[
41
+ interesting_facts.map do |fact|
42
+ [fact, FactoryBot.create(:fact_name, name: fact, type: 'Katello::RhsmFactName')]
43
+ end
44
+ ]
45
+ end
46
+
47
+ test 'generates a report for a single host' do
48
+ batches = Host.where(id: @host.id).in_batches
49
+ portal_user = 'test_portal_user'
50
+
51
+ ForemanInventoryUpload::Generators::Queries.expects(:for_report).with(portal_user).returns(batches)
52
+ Dir.mktmpdir do |tmpdir|
53
+ target = File.join(tmpdir, 'test.tar.gz')
54
+ generator = ForemanInventoryUpload::Generators::ArchivedReport.new(target, Logger.new(STDOUT))
55
+ generator.render(portal_user)
56
+
57
+ files = Dir["#{tmpdir}/*"]
58
+ assert_equal "#{tmpdir}/test.tar.gz", files.first
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,40 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class MetadataGeneratorTest < ActiveSupport::TestCase
4
+ setup do
5
+ end
6
+
7
+ test 'generates an empty report' do
8
+ generator = ForemanInventoryUpload::Generators::Metadata.new
9
+
10
+ json_str = generator.render do
11
+ end
12
+ actual = JSON.parse(json_str.join("\n"))
13
+
14
+ assert_not_nil actual['report_id']
15
+ assert_equal 'Satellite', actual['source']
16
+ assert_equal({}, actual['report_slices'])
17
+ end
18
+
19
+ test 'generates a report for a single slice' do
20
+ generator = ForemanInventoryUpload::Generators::Metadata.new
21
+
22
+ json_str = generator.render do |gen|
23
+ gen.add_slice('test_123', 1, true)
24
+ gen.add_slice('test_1234', 2, false)
25
+ gen.add_slice('test_12345', 3, false)
26
+ end
27
+
28
+ actual = JSON.parse(json_str.join("\n"))
29
+
30
+ assert_not_nil actual['report_id']
31
+ assert_equal 'Satellite', actual['source']
32
+ assert_not_nil(slices = actual['report_slices'])
33
+ assert_not_nil(slice = slices['test_123'])
34
+ assert_equal 1, slice['number_hosts']
35
+ assert_not_nil(slice = slices['test_1234'])
36
+ assert_equal 2, slice['number_hosts']
37
+ assert_not_nil(slice = slices['test_12345'])
38
+ assert_equal 3, slice['number_hosts']
39
+ end
40
+ end