hammer_cli_csv 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|