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.
- checksums.yaml +7 -0
- data/LICENSE +619 -0
- data/README.md +38 -0
- data/Rakefile +47 -0
- data/app/controllers/foreman_inventory_upload/react_controller.rb +7 -0
- data/app/controllers/foreman_inventory_upload/reports_controller.rb +23 -0
- data/app/controllers/foreman_inventory_upload/statuses_controller.rb +41 -0
- data/app/controllers/foreman_inventory_upload/uploads_controller.rb +31 -0
- data/app/helpers/foreman_inventory_upload_helper.rb +13 -0
- data/app/views/dashboard/_inventory_upload_widget.html.erb +2 -0
- data/app/views/foreman_inventory_upload/layouts/react.html.erb +16 -0
- data/app/views/scripts/uploader.sh.erb +31 -0
- data/config/routes.rb +10 -0
- data/lib/foreman_inventory_upload/async/generate_report_job.rb +29 -0
- data/lib/foreman_inventory_upload/async/progress_output.rb +61 -0
- data/lib/foreman_inventory_upload/async/queue_for_upload_job.rb +52 -0
- data/lib/foreman_inventory_upload/async/shell_process.rb +35 -0
- data/lib/foreman_inventory_upload/async/upload_report_job.rb +40 -0
- data/lib/foreman_inventory_upload/engine.rb +52 -0
- data/lib/foreman_inventory_upload/generators/archived_report.rb +53 -0
- data/lib/foreman_inventory_upload/generators/json_stream.rb +55 -0
- data/lib/foreman_inventory_upload/generators/metadata.rb +36 -0
- data/lib/foreman_inventory_upload/generators/queries.rb +52 -0
- data/lib/foreman_inventory_upload/generators/slice.rb +117 -0
- data/lib/foreman_inventory_upload/version.rb +3 -0
- data/lib/foreman_inventory_upload.rb +48 -0
- data/lib/tasks/foreman_inventory_upload_tasks.rake +37 -0
- data/lib/tasks/generator.rake +15 -0
- data/locale/Makefile +60 -0
- data/locale/en/foreman_yupana.po +19 -0
- data/locale/foreman_yupana.pot +19 -0
- data/locale/gemspec.rb +2 -0
- data/test/controllers/reports_controller_test.rb +21 -0
- data/test/controllers/statuses_controller_test.rb +26 -0
- data/test/controllers/uploads_controller_test.rb +21 -0
- data/test/factories/inventory_upload_factories.rb +88 -0
- data/test/test_plugin_helper.rb +26 -0
- data/test/unit/archived_report_generator_test.rb +61 -0
- data/test/unit/metadata_generator_test.rb +40 -0
- data/test/unit/shell_process_job_test.rb +27 -0
- data/test/unit/slice_generator_test.rb +60 -0
- 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,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,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
|