hammer_cli_csv 1.0.0 → 1.0.1
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 +8 -8
- data/config/cli_config.yml +30 -0
- data/config/csv.yml +2 -0
- data/lib/hammer_cli_csv.rb +5 -0
- data/lib/hammer_cli_csv/activation_keys.rb +36 -33
- data/lib/hammer_cli_csv/base.rb +82 -17
- data/lib/hammer_cli_csv/content_hosts.rb +100 -98
- data/lib/hammer_cli_csv/content_view_filters.rb +6 -0
- data/lib/hammer_cli_csv/content_views.rb +58 -37
- data/lib/hammer_cli_csv/export.rb +1 -1
- data/lib/hammer_cli_csv/host_collections.rb +21 -31
- data/lib/hammer_cli_csv/import.rb +13 -10
- data/lib/hammer_cli_csv/lifecycle_environments.rb +9 -3
- data/lib/hammer_cli_csv/products.rb +44 -23
- data/lib/hammer_cli_csv/provisioning_templates.rb +61 -29
- data/lib/hammer_cli_csv/roles.rb +8 -8
- data/lib/hammer_cli_csv/splice.rb +376 -0
- data/lib/hammer_cli_csv/subscriptions.rb +6 -16
- data/lib/hammer_cli_csv/sync_plans.rb +122 -0
- data/lib/hammer_cli_csv/users.rb +6 -2
- data/lib/hammer_cli_csv/version.rb +1 -1
- data/test/data/content-hosts.csv +3 -3
- data/test/data/content-view-filters.csv +1 -1
- data/test/data/organizations.csv +0 -1
- data/test/data/roles.csv +0 -1
- data/test/data/subscriptions.csv +0 -2
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MGJkZWM3ZjQ5NzFhZmJiMGU1NDI5MDcyZGY5MjgyYWMzYzdmYjlkZQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NDcxOGFmM2Y0YmRkOTAzMzg2Nzg4M2MxNWEzZTEwYzIzNGVkNjNhZg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZDhjYTkwMDEyYWY1MWMwNDkxNDQwNmMxZmNiODBiNWNjNmMxOTY0ZGE3Mjhi
|
10
|
+
OTc2ODVmZjU3ZmE2Yjk2ZWRkM2U3NjczYjhhNmE3YjcxY2YwZmU5MzUxYmFl
|
11
|
+
OGI0MjNmMTBjMWFkNDYxYzEyNzZjZmU0YjQzNmY5MGYxMWFiMjQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YmIxNmEzNWQ3MzQ5MDc0Y2U1YmQwYTkzYzdmYWViNzhkNjdjZjJhOTc4MTIw
|
14
|
+
MzM2OTgxOGEzN2IxZDAzOWI1MzdiZDQ4ZTM5MmU1MjJjNDQ2ZTQwNjRkMzI0
|
15
|
+
NWMwZDdiNTRmNjFiYmM4MmNlYjA1ZjdiZGZkZjQ0OWViN2FkN2U=
|
@@ -0,0 +1,30 @@
|
|
1
|
+
:ui:
|
2
|
+
:interactive: true
|
3
|
+
:per_page: 20
|
4
|
+
:history_file: './log/history'
|
5
|
+
|
6
|
+
:watch_plain: true # enable/disable color output of logger in Clamp commands
|
7
|
+
|
8
|
+
:log_dir: './log'
|
9
|
+
:log_level: 'error'
|
10
|
+
:log_api_calls: false
|
11
|
+
:log_size: 5 # MB
|
12
|
+
|
13
|
+
:foreman:
|
14
|
+
:enable_module: true
|
15
|
+
:host: 'http://katello:3000'
|
16
|
+
:username: 'admin'
|
17
|
+
:password: 'changeme'
|
18
|
+
|
19
|
+
:katello:
|
20
|
+
:enable_module: true
|
21
|
+
|
22
|
+
:csv:
|
23
|
+
:enable_module: true
|
24
|
+
:host: 'http://katello:3000'
|
25
|
+
:username: 'admin'
|
26
|
+
:password: 'changeme'
|
27
|
+
:products_sync: false
|
28
|
+
|
29
|
+
:gutterball:
|
30
|
+
:enable_module: true
|
data/config/csv.yml
ADDED
data/lib/hammer_cli_csv.rb
CHANGED
@@ -13,6 +13,9 @@ require 'hammer_cli'
|
|
13
13
|
require 'hammer_cli/exit_codes'
|
14
14
|
|
15
15
|
module HammerCLICsv
|
16
|
+
require 'hammer_cli_foreman'
|
17
|
+
require 'hammer_cli_foreman_tasks'
|
18
|
+
|
16
19
|
require 'hammer_cli_csv/base'
|
17
20
|
require 'hammer_cli_csv/exception_handler'
|
18
21
|
|
@@ -43,8 +46,10 @@ module HammerCLICsv
|
|
43
46
|
require 'hammer_cli_csv/reports'
|
44
47
|
require 'hammer_cli_csv/roles'
|
45
48
|
require 'hammer_cli_csv/smart_proxies'
|
49
|
+
require 'hammer_cli_csv/splice'
|
46
50
|
require 'hammer_cli_csv/subnets'
|
47
51
|
require 'hammer_cli_csv/subscriptions'
|
52
|
+
require 'hammer_cli_csv/sync_plans'
|
48
53
|
require 'hammer_cli_csv/users'
|
49
54
|
|
50
55
|
require 'hammer_cli_csv/headpin_api'
|
@@ -13,7 +13,9 @@ module HammerCLICsv
|
|
13
13
|
class CsvCommand
|
14
14
|
class ActivationKeysCommand < BaseCommand
|
15
15
|
command_name 'activation-keys'
|
16
|
-
desc 'import or export activation keys'
|
16
|
+
desc _('import or export activation keys')
|
17
|
+
|
18
|
+
option %w(--organization), 'ORGANIZATION', _('Only process organization matching this name')
|
17
19
|
|
18
20
|
ORGANIZATION = 'Organization'
|
19
21
|
DESCRIPTION = 'Description'
|
@@ -29,6 +31,8 @@ module HammerCLICsv
|
|
29
31
|
HOSTCOLLECTIONS, SUBSCRIPTIONS]
|
30
32
|
if @server_status['release'] == 'Headpin'
|
31
33
|
@headpin.get(:organizations).each do |organization|
|
34
|
+
next if option_organization && organization['name'] != option_organization
|
35
|
+
|
32
36
|
@headpin.get("organizations/#{organization['label']}/activation_keys").each do |activationkey|
|
33
37
|
name = namify(activationkey['name'])
|
34
38
|
count = 1
|
@@ -54,6 +58,8 @@ module HammerCLICsv
|
|
54
58
|
@api.resource(:organizations).call(:index, {
|
55
59
|
:per_page => 999999
|
56
60
|
})['results'].each do |organization|
|
61
|
+
next if option_organization && organization['name'] != option_organization
|
62
|
+
|
57
63
|
@api.resource(:activation_keys).call(:index, {
|
58
64
|
'per_page' => 999999,
|
59
65
|
'organization_id' => organization['id']
|
@@ -61,20 +67,22 @@ module HammerCLICsv
|
|
61
67
|
name = namify(activationkey['name'])
|
62
68
|
count = 1
|
63
69
|
description = activationkey['description']
|
64
|
-
limit = activationkey['
|
70
|
+
limit = activationkey['unlimited_content_hosts'] ? 'Unlimited' : activationkey['max_content_hosts']
|
65
71
|
environment = activationkey['environment']['label']
|
66
72
|
contentview = activationkey['content_view']['name']
|
67
73
|
hostcollections = export_column(activationkey, 'systemGroups', 'name')
|
68
74
|
subscriptions = CSV.generate do |column|
|
69
75
|
column << @api.resource(:subscriptions).call(:index, {
|
70
|
-
|
71
|
-
|
76
|
+
'organization_id' => organization['id'],
|
77
|
+
'activation_key_id' => activationkey['id']
|
78
|
+
})['results'].collect do |subscription|
|
72
79
|
amount = subscription['amount'] == 0 ? 'Automatic' : subscription['amount']
|
73
|
-
|
80
|
+
sku = subscription['product_id'].match(/\A[0-9]/) ? 'Custom' : subscription['product_id']
|
81
|
+
"#{amount}|#{sku}|#{subscription['product_name']}"
|
74
82
|
end
|
75
83
|
end
|
76
84
|
subscriptions.delete!("\n")
|
77
|
-
csv << [name, count, organization['
|
85
|
+
csv << [name, count, organization['name'], description, limit, environment, contentview,
|
78
86
|
hostcollections, subscriptions]
|
79
87
|
end
|
80
88
|
end
|
@@ -91,6 +99,8 @@ module HammerCLICsv
|
|
91
99
|
end
|
92
100
|
|
93
101
|
def create_activationkeys_from_csv(line)
|
102
|
+
return if option_organization && line[ORGANIZATION] != option_organization
|
103
|
+
|
94
104
|
if !@existing[line[ORGANIZATION]]
|
95
105
|
@existing[line[ORGANIZATION]] = {}
|
96
106
|
@api.resource(:activation_keys).call(:index, {
|
@@ -104,38 +114,31 @@ module HammerCLICsv
|
|
104
114
|
line[COUNT].to_i.times do |number|
|
105
115
|
name = namify(line[NAME], number)
|
106
116
|
|
117
|
+
params = {
|
118
|
+
'organization_id' => foreman_organization(:name => line[ORGANIZATION]),
|
119
|
+
'name' => name,
|
120
|
+
'environment_id' => lifecycle_environment(line[ORGANIZATION],
|
121
|
+
:name => line[ENVIRONMENT]),
|
122
|
+
'content_view_id' => katello_contentview(line[ORGANIZATION],
|
123
|
+
:name => line[CONTENTVIEW]),
|
124
|
+
'description' => line[DESCRIPTION],
|
125
|
+
'unlimited_content_hosts' => (line[LIMIT] == 'Unlimited') ? true : false,
|
126
|
+
'max_content_hosts' => (line[LIMIT] == 'Unlimited') ? nil : line[LIMIT].to_i
|
127
|
+
}
|
107
128
|
if !@existing[line[ORGANIZATION]].include? name
|
108
|
-
print "Creating activation key '
|
109
|
-
activationkey = @api.resource(:activation_keys).call(:create,
|
110
|
-
'organization_id' => foreman_organization(:name => line[ORGANIZATION]),
|
111
|
-
'name' => name,
|
112
|
-
'environment_id' => lifecycle_environment(line[ORGANIZATION],
|
113
|
-
:name => line[ENVIRONMENT]),
|
114
|
-
'content_view_id' => katello_contentview(line[ORGANIZATION],
|
115
|
-
:name => line[CONTENTVIEW]),
|
116
|
-
'description' => line[DESCRIPTION],
|
117
|
-
'usage_limit' => usage_limit(line[LIMIT])
|
118
|
-
})
|
129
|
+
print _("Creating activation key '%{name}'...") % {:name => name} if option_verbose?
|
130
|
+
activationkey = @api.resource(:activation_keys).call(:create, params)
|
119
131
|
@existing[line[ORGANIZATION]][activationkey['name']] = activationkey['id']
|
120
132
|
else
|
121
|
-
print "Updating activation key '
|
122
|
-
|
123
|
-
|
124
|
-
'id' => @existing[line[ORGANIZATION]][name],
|
125
|
-
'name' => name,
|
126
|
-
'environment_id' => lifecycle_environment(line[ORGANIZATION],
|
127
|
-
:name => line[ENVIRONMENT]),
|
128
|
-
'content_view_id' => katello_contentview(line[ORGANIZATION],
|
129
|
-
:name => line[CONTENTVIEW]),
|
130
|
-
'description' => line[DESCRIPTION],
|
131
|
-
'usage_limit' => usage_limit(line[LIMIT])
|
132
|
-
})
|
133
|
-
|
134
|
-
update_subscriptions(activationkey, line)
|
135
|
-
update_groups(activationkey, line)
|
133
|
+
print _("Updating activation key '%{name}'...") % {:name => name} if option_verbose?
|
134
|
+
params['id'] = @existing[line[ORGANIZATION]][name]
|
135
|
+
activationkey = @api.resource(:activation_keys).call(:update, params)
|
136
136
|
end
|
137
137
|
|
138
|
-
|
138
|
+
update_subscriptions(activationkey, line)
|
139
|
+
update_groups(activationkey, line)
|
140
|
+
|
141
|
+
puts _('done') if option_verbose?
|
139
142
|
end
|
140
143
|
end
|
141
144
|
|
data/lib/hammer_cli_csv/base.rb
CHANGED
@@ -75,6 +75,18 @@ module HammerCLICsv
|
|
75
75
|
JSON.parse(response.body)
|
76
76
|
end
|
77
77
|
|
78
|
+
url = "#{server}/api/v2/plugins"
|
79
|
+
uri = URI(url)
|
80
|
+
nethttp = Net::HTTP.new(uri.host, uri.port)
|
81
|
+
nethttp.use_ssl = uri.scheme == 'https'
|
82
|
+
nethttp.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
83
|
+
server_status['plugins'] = nethttp.start do |http|
|
84
|
+
request = Net::HTTP::Get.new uri.request_uri
|
85
|
+
request.basic_auth(username, password)
|
86
|
+
response = http.request(request)
|
87
|
+
JSON.parse(response.body)['results']
|
88
|
+
end
|
89
|
+
|
78
90
|
server_status
|
79
91
|
end
|
80
92
|
|
@@ -92,13 +104,14 @@ module HammerCLICsv
|
|
92
104
|
name.gsub(/[^a-z0-9\-_]/i, '_')
|
93
105
|
end
|
94
106
|
|
95
|
-
def thread_import(return_headers = false)
|
107
|
+
def thread_import(return_headers = false, filename=nil, name_column=nil)
|
108
|
+
filename ||= option_csv_file || '/dev/stdin'
|
96
109
|
csv = []
|
97
|
-
CSV.foreach(
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
110
|
+
CSV.foreach(filename, {
|
111
|
+
:skip_blanks => true,
|
112
|
+
:headers => :first_row,
|
113
|
+
:return_headers => return_headers
|
114
|
+
}) do |line|
|
102
115
|
csv << line
|
103
116
|
end
|
104
117
|
lines_per_thread = csv.length / option_threads.to_i + 1
|
@@ -112,7 +125,7 @@ module HammerCLICsv
|
|
112
125
|
lines = csv[start_index...finish_index].clone
|
113
126
|
splits << Thread.new do
|
114
127
|
lines.each do |line|
|
115
|
-
if line[NAME][0] != '#'
|
128
|
+
if line[name_column || NAME][0] != '#'
|
116
129
|
yield line
|
117
130
|
end
|
118
131
|
end
|
@@ -534,7 +547,7 @@ module HammerCLICsv
|
|
534
547
|
result
|
535
548
|
end
|
536
549
|
|
537
|
-
def katello_contentviewversion(organization, name, version)
|
550
|
+
def katello_contentviewversion(organization, name, version='latest')
|
538
551
|
@contentviewversions ||= {}
|
539
552
|
@contentviewversions[organization] ||= {}
|
540
553
|
versionname = "#{version}|#{name}"
|
@@ -543,12 +556,17 @@ module HammerCLICsv
|
|
543
556
|
id = @contentviewversions[organization][versionname]
|
544
557
|
if !id
|
545
558
|
contentview_id = katello_contentview(organization, :name => name)
|
546
|
-
@api.resource(:content_view_versions).call(:index, {
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
559
|
+
contentviewversions = @api.resource(:content_view_versions).call(:index, {
|
560
|
+
:per_page => 999999,
|
561
|
+
'content_view_id' => contentview_id
|
562
|
+
})['results'].sort { |a, b| a['created_at'] <=> b['created_at'] }
|
563
|
+
if version == 'latest'
|
564
|
+
@contentviewversions[organization][versionname] = contentviewversions[-1]['id']
|
565
|
+
else
|
566
|
+
contentviewversions.each do |contentviewversion|
|
567
|
+
if contentviewversion['version'] == version.to_f
|
568
|
+
@contentviewversions[organization][versionname] = contentviewversion['id']
|
569
|
+
end
|
552
570
|
end
|
553
571
|
end
|
554
572
|
id = @contentviewversions[organization][versionname]
|
@@ -639,12 +657,12 @@ module HammerCLICsv
|
|
639
657
|
{
|
640
658
|
:per_page => 999999,
|
641
659
|
'organization_id' => foreman_organization(:name => organization),
|
642
|
-
'search' =>
|
660
|
+
'search' => search_string('host-collections',options[:name])
|
643
661
|
})['results'].each do |hostcollection|
|
644
662
|
@hostcollections[organization][hostcollection['name']] = hostcollection['id'] if hostcollection
|
645
663
|
end
|
646
664
|
options[:id] = @hostcollections[organization][options[:name]]
|
647
|
-
raise "
|
665
|
+
raise "Host collection '#{options[:name]}' not found" if !options[:id]
|
648
666
|
end
|
649
667
|
result = options[:id]
|
650
668
|
else
|
@@ -652,7 +670,7 @@ module HammerCLICsv
|
|
652
670
|
options[:name] = @hostcollections.key(options[:id])
|
653
671
|
if !options[:name]
|
654
672
|
hostcollection = @api.resource(:host_collections).call(:show, {'id' => options[:id]})
|
655
|
-
raise "
|
673
|
+
raise "Host collection '#{options[:name]}' not found" if !hostcollection || hostcollection.empty?
|
656
674
|
options[:name] = hostcollection['name']
|
657
675
|
@hostcollections[options[:name]] = options[:id]
|
658
676
|
end
|
@@ -662,6 +680,41 @@ module HammerCLICsv
|
|
662
680
|
result
|
663
681
|
end
|
664
682
|
|
683
|
+
def katello_product(organization, options = {})
|
684
|
+
@products ||= {}
|
685
|
+
@products[organization] ||= {}
|
686
|
+
|
687
|
+
if options[:name]
|
688
|
+
return nil if options[:name].nil? || options[:name].empty?
|
689
|
+
options[:id] = @products[organization][options[:name]]
|
690
|
+
if !options[:id]
|
691
|
+
@api.resource(:products).call(:index,
|
692
|
+
{
|
693
|
+
:per_page => 999999,
|
694
|
+
'organization_id' => foreman_organization(:name => organization),
|
695
|
+
'search' => search_string('host-collections',options[:name])
|
696
|
+
})['results'].each do |product|
|
697
|
+
@products[organization][product['name']] = product['id'] if product
|
698
|
+
end
|
699
|
+
options[:id] = @products[organization][options[:name]]
|
700
|
+
raise "Host collection '#{options[:name]}' not found" if !options[:id]
|
701
|
+
end
|
702
|
+
result = options[:id]
|
703
|
+
else
|
704
|
+
return nil if options[:id].nil?
|
705
|
+
options[:name] = @products.key(options[:id])
|
706
|
+
if !options[:name]
|
707
|
+
product = @api.resource(:host_collections).call(:show, {'id' => options[:id]})
|
708
|
+
raise "Host collection '#{options[:name]}' not found" if !product || product.empty?
|
709
|
+
options[:name] = product['name']
|
710
|
+
@products[options[:name]] = options[:id]
|
711
|
+
end
|
712
|
+
result = options[:name]
|
713
|
+
end
|
714
|
+
|
715
|
+
result
|
716
|
+
end
|
717
|
+
|
665
718
|
def build_os_name(name, major, minor)
|
666
719
|
name += " #{major}" if major && major != ''
|
667
720
|
name += ".#{minor}" if minor && minor != ''
|
@@ -750,5 +803,17 @@ module HammerCLICsv
|
|
750
803
|
})
|
751
804
|
end if locations && !locations.empty?
|
752
805
|
end
|
806
|
+
|
807
|
+
private
|
808
|
+
|
809
|
+
def search_string(resource, name)
|
810
|
+
operator = case resource
|
811
|
+
when "gpg-key", "sync-plan", "lifecycle-environment", "host-collections"
|
812
|
+
@server_status['version'] && @server_status['version'].match(/\A1\.6/) ? ':' : '='
|
813
|
+
else
|
814
|
+
':'
|
815
|
+
end
|
816
|
+
"name#{operator}\"#{name}\""
|
817
|
+
end
|
753
818
|
end
|
754
819
|
end
|
@@ -9,35 +9,15 @@
|
|
9
9
|
# have received a copy of GPLv2 along with this software; if not, see
|
10
10
|
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
|
11
11
|
|
12
|
-
#
|
13
|
-
# -= Systems CSV =-
|
14
|
-
#
|
15
|
-
# Columns
|
16
|
-
# Name
|
17
|
-
# - System name
|
18
|
-
# - May contain '%d' which will be replaced with current iteration number of Count
|
19
|
-
# - eg. "os%d" -> "os1"
|
20
|
-
# Count
|
21
|
-
# - Number of times to iterate on this line of the CSV file
|
22
|
-
# MAC Address
|
23
|
-
# - MAC address
|
24
|
-
# - May contain '%d' which will be replaced with current iteration number of Count
|
25
|
-
# - eg. "FF:FF:FF:FF:FF:%02x" -> "FF:FF:FF:FF:FF:0A"
|
26
|
-
# - Warning: be sure to keep count below 255 or MAC hex will exceed limit
|
27
|
-
#
|
28
|
-
|
29
|
-
require 'hammer_cli'
|
30
|
-
require 'json'
|
31
|
-
require 'csv'
|
32
|
-
require 'uri'
|
33
|
-
|
34
12
|
module HammerCLICsv
|
35
13
|
class CsvCommand
|
36
14
|
class ContentHostsCommand < BaseCommand
|
15
|
+
include ::HammerCLIForemanTasks::Helper
|
16
|
+
|
37
17
|
command_name 'content-hosts'
|
38
18
|
desc 'import or export content hosts'
|
39
19
|
|
40
|
-
option %w(--
|
20
|
+
option %w(--organization), 'ORGANIZATION', 'Only process organization matching this name'
|
41
21
|
|
42
22
|
ORGANIZATION = 'Organization'
|
43
23
|
ENVIRONMENT = 'Environment'
|
@@ -67,92 +47,94 @@ module HammerCLICsv
|
|
67
47
|
end
|
68
48
|
|
69
49
|
def export_sam(csv)
|
70
|
-
|
71
|
-
|
50
|
+
guests_hypervisor = {}
|
51
|
+
host_ids = []
|
72
52
|
|
73
53
|
@headpin.get(:organizations).each do |organization|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
54
|
+
next if option_organization && organization['name'] != option_organization
|
55
|
+
host_ids = @headpin.get("organizations/#{organization['label']}/systems").collect do |host|
|
56
|
+
host['guests'].each { |guest| guests_hypervisor[guest['uuid']] = host['name'] }
|
57
|
+
host['uuid']
|
78
58
|
end
|
79
59
|
end
|
80
60
|
|
81
|
-
|
82
|
-
|
83
|
-
|
61
|
+
host_ids.each do |host_id|
|
62
|
+
host = @headpin.get("systems/#{host_id}")
|
63
|
+
host_subscriptions = @headpin.get("systems/#{host_id}/subscriptions")['entitlements']
|
84
64
|
|
85
|
-
name =
|
65
|
+
name = host['name']
|
86
66
|
count = 1
|
87
|
-
organization_name =
|
88
|
-
environment =
|
89
|
-
contentview =
|
67
|
+
organization_name = host['owner']['displayName']
|
68
|
+
environment = host['environment']['name']
|
69
|
+
contentview = host['content_view']['name']
|
90
70
|
hostcollections = nil
|
91
|
-
virtual =
|
92
|
-
|
93
|
-
if
|
94
|
-
operatingsystem = "#{
|
95
|
-
operatingsystem +=
|
71
|
+
virtual = host['facts']['virt.is_guest'] == 'true' ? 'Yes' : 'No'
|
72
|
+
hypervisor = guests_hypervisor[host['uuid']]
|
73
|
+
if host['facts']['distribution.name']
|
74
|
+
operatingsystem = "#{host['facts']['distribution.name']} "
|
75
|
+
operatingsystem += host['facts']['distribution.version'] if host['facts']['distribution.version']
|
96
76
|
operatingsystem.strip!
|
97
77
|
end
|
98
|
-
architecture =
|
99
|
-
sockets =
|
100
|
-
ram =
|
101
|
-
cores =
|
102
|
-
sla =
|
78
|
+
architecture = host['facts']['uname.machine']
|
79
|
+
sockets = host['facts']['cpu.cpu_socket(s)']
|
80
|
+
ram = host['facts']['memory.memtotal']
|
81
|
+
cores = host['facts']['cpu.core(s)_per_socket'] || 1
|
82
|
+
sla = host['serviceLevel']
|
103
83
|
|
104
84
|
products = CSV.generate do |column|
|
105
|
-
column <<
|
85
|
+
column << host['installedProducts'].collect do |product|
|
106
86
|
"#{product['productId']}|#{product['productName']}"
|
107
87
|
end
|
108
88
|
end
|
109
89
|
products.delete!("\n")
|
110
90
|
|
111
91
|
subscriptions = CSV.generate do |column|
|
112
|
-
column <<
|
92
|
+
column << host_subscriptions.collect do |subscription|
|
113
93
|
"#{subscription['quantity']}|#{subscription['productId']}|#{subscription['poolName']}"
|
114
94
|
end
|
115
95
|
end
|
116
96
|
subscriptions.delete!("\n")
|
117
97
|
|
118
|
-
csv << [name, count, organization_name, environment, contentview, hostcollections, virtual,
|
98
|
+
csv << [name, count, organization_name, environment, contentview, hostcollections, virtual, hypervisor,
|
119
99
|
operatingsystem, architecture, sockets, ram, cores, sla, products, subscriptions]
|
120
100
|
end
|
121
101
|
end
|
122
102
|
|
123
103
|
def export_foretello(csv)
|
124
104
|
@api.resource(:organizations).call(:index, {:per_page => 999999})['results'].each do |organization|
|
105
|
+
next if option_organization && organization['name'] != option_organization
|
106
|
+
|
125
107
|
@api.resource(:systems).call(:index, {
|
126
108
|
'per_page' => 999999,
|
127
109
|
'organization_id' => foreman_organization(:name => organization['name'])
|
128
|
-
})['results'].each do |
|
129
|
-
|
130
|
-
'id' =>
|
110
|
+
})['results'].each do |host|
|
111
|
+
host = @api.resource(:systems).call(:show, {
|
112
|
+
'id' => host['uuid'],
|
131
113
|
'fields' => 'full'
|
132
114
|
})
|
133
115
|
|
134
|
-
name =
|
116
|
+
name = host['name']
|
135
117
|
count = 1
|
136
118
|
organization_name = organization['name']
|
137
|
-
environment =
|
138
|
-
contentview =
|
119
|
+
environment = host['environment']['label']
|
120
|
+
contentview = host['content_view']['name']
|
139
121
|
hostcollections = CSV.generate do |column|
|
140
|
-
column <<
|
122
|
+
column << host['hostCollections'].collect do |hostcollection|
|
141
123
|
hostcollection['name']
|
142
124
|
end
|
143
125
|
end
|
144
126
|
hostcollections.delete!("\n")
|
145
|
-
virtual =
|
146
|
-
|
147
|
-
operatingsystem = "#{
|
148
|
-
operatingsystem +=
|
149
|
-
architecture =
|
150
|
-
sockets =
|
151
|
-
ram =
|
152
|
-
cores =
|
127
|
+
virtual = host['facts']['virt.is_guest'] == 'true' ? 'Yes' : 'No'
|
128
|
+
hypervisor_host = host['virtual_host'].nil? ? nil : host['virtual_host']['name']
|
129
|
+
operatingsystem = "#{host['facts']['distribution.name']} " if host['facts']['distribution.name']
|
130
|
+
operatingsystem += host['facts']['distribution.version'] if host['facts']['distribution.version']
|
131
|
+
architecture = host['facts']['uname.machine']
|
132
|
+
sockets = host['facts']['cpu.cpu_socket(s)']
|
133
|
+
ram = host['facts']['memory.memtotal']
|
134
|
+
cores = host['facts']['cpu.core(s)_per_socket'] || 1
|
153
135
|
sla = ''
|
154
136
|
products = CSV.generate do |column|
|
155
|
-
column <<
|
137
|
+
column << host['installedProducts'].collect do |product|
|
156
138
|
"#{product['productId']}|#{product['productName']}"
|
157
139
|
end
|
158
140
|
end
|
@@ -160,37 +142,56 @@ module HammerCLICsv
|
|
160
142
|
subscriptions = CSV.generate do |column|
|
161
143
|
column << @api.resource(:subscriptions).call(:index, {
|
162
144
|
'organization_id' => organization['id'],
|
163
|
-
'system_id' =>
|
145
|
+
'system_id' => host['uuid']
|
164
146
|
})['results'].collect do |subscription|
|
165
147
|
"#{subscription['consumed']}|#{subscription['product_id']}|#{subscription['product_name']}"
|
166
148
|
end
|
167
149
|
end
|
168
150
|
subscriptions.delete!("\n")
|
169
|
-
csv << [name, count, organization_name, environment, contentview, hostcollections, virtual,
|
151
|
+
csv << [name, count, organization_name, environment, contentview, hostcollections, virtual, hypervisor_host,
|
170
152
|
operatingsystem, architecture, sockets, ram, cores, sla, products, subscriptions]
|
171
153
|
end
|
172
154
|
end
|
173
155
|
end
|
174
156
|
|
175
157
|
def import
|
158
|
+
remote = @server_status['plugins'].detect { |plugin| plugin['name'] == 'foreman_csv' }
|
159
|
+
if remote.nil?
|
160
|
+
import_locally
|
161
|
+
else
|
162
|
+
import_remotely
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def import_remotely
|
167
|
+
params = {'content' => ::File.new(::File.expand_path(option_csv_file), 'rb')}
|
168
|
+
headers = {:content_type => 'multipart/form-data', :multipart => true}
|
169
|
+
task_progress(@api.resource(:csv).call(:import_content_hosts, params, headers))
|
170
|
+
end
|
171
|
+
|
172
|
+
def import_locally
|
176
173
|
@existing = {}
|
177
|
-
@
|
174
|
+
@hypervisor_guests = {}
|
178
175
|
|
179
176
|
thread_import do |line|
|
180
|
-
|
177
|
+
create_content_hosts_from_csv(line)
|
181
178
|
end
|
182
179
|
|
183
|
-
|
184
|
-
|
185
|
-
@
|
186
|
-
|
187
|
-
|
188
|
-
|
180
|
+
if !@hypervisor_guests.empty?
|
181
|
+
print(_('Updating hypervisor and guest associations...')) if option_verbose?
|
182
|
+
@hypervisor_guests.each do |host_id, guest_ids|
|
183
|
+
@api.resource(:systems).call(:update, {
|
184
|
+
'id' => host_id,
|
185
|
+
'guest_ids' => guest_ids
|
186
|
+
})
|
187
|
+
end
|
189
188
|
end
|
190
|
-
puts 'done' if option_verbose?
|
189
|
+
puts _('done') if option_verbose?
|
191
190
|
end
|
192
191
|
|
193
|
-
def
|
192
|
+
def create_content_hosts_from_csv(line)
|
193
|
+
return if option_organization && line[ORGANIZATION] != option_organization
|
194
|
+
|
194
195
|
if !@existing[line[ORGANIZATION]]
|
195
196
|
@existing[line[ORGANIZATION]] = {}
|
196
197
|
# Fetching all content hosts is too slow and times out due to the complexity of the data
|
@@ -205,8 +206,8 @@ module HammerCLICsv
|
|
205
206
|
'organization_id' => foreman_organization(:name => line[ORGANIZATION]),
|
206
207
|
'page' => page,
|
207
208
|
'per_page' => 20
|
208
|
-
})['results'].each do |
|
209
|
-
@existing[line[ORGANIZATION]][
|
209
|
+
})['results'].each do |host|
|
210
|
+
@existing[line[ORGANIZATION]][host['name']] = host['uuid'] if host
|
210
211
|
end
|
211
212
|
end
|
212
213
|
end
|
@@ -215,8 +216,8 @@ module HammerCLICsv
|
|
215
216
|
name = namify(line[NAME], number)
|
216
217
|
|
217
218
|
if !@existing[line[ORGANIZATION]].include? name
|
218
|
-
print
|
219
|
-
|
219
|
+
print(_("Creating content host '%{name}'...") % {:name => name}) if option_verbose?
|
220
|
+
host_id = @api.resource(:systems).call(:create, {
|
220
221
|
'name' => name,
|
221
222
|
'organization_id' => foreman_organization(:name => line[ORGANIZATION]),
|
222
223
|
'environment_id' => lifecycle_environment(line[ORGANIZATION], :name => line[ENVIRONMENT]),
|
@@ -226,10 +227,10 @@ module HammerCLICsv
|
|
226
227
|
'service_level' => line[SLA],
|
227
228
|
'type' => 'system'
|
228
229
|
})['uuid']
|
229
|
-
@existing[line[ORGANIZATION]][name] =
|
230
|
+
@existing[line[ORGANIZATION]][name] = host_id
|
230
231
|
else
|
231
|
-
print
|
232
|
-
|
232
|
+
print(_("Updating content host '%{name}'...") % {:name => name}) if option_verbose?
|
233
|
+
host_id = @api.resource(:systems).call(:update, {
|
233
234
|
'id' => @existing[line[ORGANIZATION]][name],
|
234
235
|
'system' => {
|
235
236
|
'name' => name,
|
@@ -238,6 +239,7 @@ module HammerCLICsv
|
|
238
239
|
'facts' => facts(name, line),
|
239
240
|
'installed_products' => products(line)
|
240
241
|
},
|
242
|
+
'facts' => facts(name, line),
|
241
243
|
'installed_products' => products(line), # TODO: http://projects.theforeman.org/issues/9191,
|
242
244
|
'service_level' => line[SLA]
|
243
245
|
})['uuid']
|
@@ -245,14 +247,14 @@ module HammerCLICsv
|
|
245
247
|
|
246
248
|
if line[VIRTUAL] == 'Yes' && line[HOST]
|
247
249
|
raise "Content host '#{line[HOST]}' not found" if !@existing[line[ORGANIZATION]][line[HOST]]
|
248
|
-
@
|
249
|
-
@
|
250
|
+
@hypervisor_guests[@existing[line[ORGANIZATION]][line[HOST]]] ||= []
|
251
|
+
@hypervisor_guests[@existing[line[ORGANIZATION]][line[HOST]]] << "#{line[ORGANIZATION]}/#{name}"
|
250
252
|
end
|
251
253
|
|
252
|
-
update_host_collections(
|
253
|
-
update_subscriptions(
|
254
|
+
update_host_collections(host_id, line)
|
255
|
+
update_subscriptions(host_id, line)
|
254
256
|
|
255
|
-
puts 'done' if option_verbose?
|
257
|
+
puts _('done') if option_verbose?
|
256
258
|
end
|
257
259
|
rescue RuntimeError => e
|
258
260
|
raise "#{e}\n #{line}"
|
@@ -275,12 +277,12 @@ module HammerCLICsv
|
|
275
277
|
facts
|
276
278
|
end
|
277
279
|
|
278
|
-
def update_host_collections(
|
280
|
+
def update_host_collections(host_id, line)
|
279
281
|
return nil if !line[HOSTCOLLECTIONS]
|
280
282
|
CSV.parse_line(line[HOSTCOLLECTIONS]).each do |hostcollection_name|
|
281
283
|
@api.resource(:host_collections).call(:add_systems, {
|
282
284
|
'id' => katello_hostcollection(line[ORGANIZATION], :name => hostcollection_name),
|
283
|
-
'system_ids' => [
|
285
|
+
'system_ids' => [host_id]
|
284
286
|
})
|
285
287
|
end
|
286
288
|
end
|
@@ -311,16 +313,16 @@ module HammerCLICsv
|
|
311
313
|
products
|
312
314
|
end
|
313
315
|
|
314
|
-
def update_subscriptions(
|
316
|
+
def update_subscriptions(host_id, line)
|
315
317
|
existing_subscriptions = @api.resource(:subscriptions).call(:index, {
|
316
318
|
'organization_id' => foreman_organization(:name => line[ORGANIZATION]),
|
317
319
|
'per_page' => 999999,
|
318
|
-
'system_id' =>
|
320
|
+
'system_id' => host_id
|
319
321
|
})['results']
|
320
322
|
if existing_subscriptions.length > 0
|
321
|
-
@api.resource(:
|
322
|
-
'
|
323
|
-
'
|
323
|
+
@api.resource(:subscriptions).call(:destroy, {
|
324
|
+
'system_id' => host_id,
|
325
|
+
'id' => existing_subscriptions[0]['id']
|
324
326
|
})
|
325
327
|
end
|
326
328
|
|
@@ -330,12 +332,12 @@ module HammerCLICsv
|
|
330
332
|
(amount, sku, name) = details.split('|')
|
331
333
|
{
|
332
334
|
:id => katello_subscription(line[ORGANIZATION], :name => name),
|
333
|
-
:quantity => (amount.nil? || amount.empty? || amount == 'Automatic') ? 0 : amount
|
335
|
+
:quantity => (amount.nil? || amount.empty? || amount == 'Automatic') ? 0 : amount.to_i
|
334
336
|
}
|
335
337
|
end
|
336
338
|
|
337
339
|
@api.resource(:subscriptions).call(:create, {
|
338
|
-
'system_id' =>
|
340
|
+
'system_id' => host_id,
|
339
341
|
'subscriptions' => subscriptions
|
340
342
|
})
|
341
343
|
end
|