hammer_cli_csv 0.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 +15 -0
- data/lib/hammer_cli_csv.rb +48 -0
- data/lib/hammer_cli_csv/activation_keys.rb +170 -0
- data/lib/hammer_cli_csv/architectures.rb +95 -0
- data/lib/hammer_cli_csv/base.rb +706 -0
- data/lib/hammer_cli_csv/compute_profiles.rb +94 -0
- data/lib/hammer_cli_csv/compute_resources.rb +92 -0
- data/lib/hammer_cli_csv/content_hosts.rb +357 -0
- data/lib/hammer_cli_csv/content_view_filters.rb +158 -0
- data/lib/hammer_cli_csv/content_views.rb +86 -0
- data/lib/hammer_cli_csv/csv.rb +23 -0
- data/lib/hammer_cli_csv/domains.rb +103 -0
- data/lib/hammer_cli_csv/exception_handler.rb +53 -0
- data/lib/hammer_cli_csv/host_collections.rb +108 -0
- data/lib/hammer_cli_csv/hosts.rb +118 -0
- data/lib/hammer_cli_csv/import.rb +82 -0
- data/lib/hammer_cli_csv/installation_medias.rb +88 -0
- data/lib/hammer_cli_csv/lifecycle_environments.rb +116 -0
- data/lib/hammer_cli_csv/locations.rb +84 -0
- data/lib/hammer_cli_csv/operating_systems.rb +95 -0
- data/lib/hammer_cli_csv/organizations.rb +107 -0
- data/lib/hammer_cli_csv/partition_tables.rb +98 -0
- data/lib/hammer_cli_csv/products.rb +179 -0
- data/lib/hammer_cli_csv/provisioning_templates.rb +96 -0
- data/lib/hammer_cli_csv/puppet_environments.rb +105 -0
- data/lib/hammer_cli_csv/puppet_facts.rb +99 -0
- data/lib/hammer_cli_csv/puppet_reports.rb +244 -0
- data/lib/hammer_cli_csv/reports.rb +91 -0
- data/lib/hammer_cli_csv/roles.rb +115 -0
- data/lib/hammer_cli_csv/smart_proxies.rb +88 -0
- data/lib/hammer_cli_csv/subnets.rb +121 -0
- data/lib/hammer_cli_csv/subscriptions.rb +135 -0
- data/lib/hammer_cli_csv/users.rb +133 -0
- data/lib/hammer_cli_csv/version.rb +16 -0
- data/test/activation_keys_test.rb +17 -0
- data/test/apipie_resource_mock.rb +77 -0
- data/test/config.template.yml +17 -0
- data/test/csv_test_helper.rb +65 -0
- data/test/data/activation-keys.csv +119 -0
- data/test/data/architectures.csv +5 -0
- data/test/data/content-hosts.csv +4 -0
- data/test/data/content-view-filters.csv +2 -0
- data/test/data/content-views.csv +6 -0
- data/test/data/domains.csv +8 -0
- data/test/data/host-collections.csv +16 -0
- data/test/data/hosts.csv +12 -0
- data/test/data/installation-medias.csv +7 -0
- data/test/data/lifecycle-environments.csv +6 -0
- data/test/data/locations.csv +10 -0
- data/test/data/operating-systems.csv +16 -0
- data/test/data/organizations.csv +5 -0
- data/test/data/partition-tables.csv +187 -0
- data/test/data/products.csv +19 -0
- data/test/data/puppet-environments.csv +6 -0
- data/test/data/puppet-facts.csv +9 -0
- data/test/data/reports.csv +4 -0
- data/test/data/roles.csv +159 -0
- data/test/data/smart-proxies.csv +2 -0
- data/test/data/subscriptions.csv +19 -0
- data/test/data/users.csv +119 -0
- data/test/helpers/command.rb +67 -0
- data/test/helpers/resource_disabled.rb +69 -0
- data/test/hosts_test.rb +47 -0
- data/test/organizations_test.rb +74 -0
- data/test/roles_test.rb +39 -0
- data/test/setup_test.rb +164 -0
- data/test/systems_test.rb +71 -0
- data/test/users_test.rb +35 -0
- metadata +174 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NzY3ZmEyZWZkYzk3MTA0NDAzMDNkNzIxYTRhNDc5ZmJhYWVjNDQ5MA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MjBjNWJhOTBhOTE1YTU2MDI3YTAwYTRhMWI4OWJmNDQxMjY5ZmI0OQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YWJjZDUxZDZiZjMwOTZiN2JlOWYwZmI0MTk0YTQwN2Y2OTYxMTdlYzc3Njlj
|
10
|
+
ZTkyNThkZjJiMzM0OTMzYTgzYWZkNjBhNDk1Y2MyMmY0M2U2MzZjYTYwMzY3
|
11
|
+
YjY0NzViZWZhNTAyNDY1NzBlNWUxYWZkMDA5MjgyMWFlZGRmYTE=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
Njg1OTg0NWMxNzRiODNkYzM4NDdhMDcyMmIzMTE2YzliNzc5ZTE0YTE3MWU3
|
14
|
+
ZjNhZGUyYTk0YjBlZTkzMTg2MzhmYjMzMDQwNDY1MzhmNWYxOWU5NDBiZjBl
|
15
|
+
MWNlYWI0MjA0MzRjYmVkNmYxZWIxZTM4MjE3OWMyOGQ1ZDIwNmQ=
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Copyright 2013-2014 Red Hat, Inc.
|
2
|
+
#
|
3
|
+
# This software is licensed to you under the GNU General Public
|
4
|
+
# License as published by the Free Software Foundation; either version
|
5
|
+
# 2 of the License (GPLv2) or (at your option) any later version.
|
6
|
+
# There is NO WARRANTY for this software, express or implied,
|
7
|
+
# including the implied warranties of MERCHANTABILITY,
|
8
|
+
# NON-INFRINGEMENT, or FITNESS FOR A PARTICULAR PURPOSE. You should
|
9
|
+
# have received a copy of GPLv2 along with this software; if not, see
|
10
|
+
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
|
11
|
+
|
12
|
+
require 'hammer_cli'
|
13
|
+
require 'hammer_cli/exit_codes'
|
14
|
+
|
15
|
+
module HammerCLICsv
|
16
|
+
require 'hammer_cli_csv/base'
|
17
|
+
require 'hammer_cli_csv/exception_handler'
|
18
|
+
|
19
|
+
require 'hammer_cli_csv/csv'
|
20
|
+
require 'hammer_cli_csv/activation_keys'
|
21
|
+
require 'hammer_cli_csv/architectures'
|
22
|
+
require 'hammer_cli_csv/compute_profiles'
|
23
|
+
require 'hammer_cli_csv/compute_resources'
|
24
|
+
require 'hammer_cli_csv/content_hosts'
|
25
|
+
require 'hammer_cli_csv/content_views'
|
26
|
+
require 'hammer_cli_csv/content_view_filters'
|
27
|
+
require 'hammer_cli_csv/domains'
|
28
|
+
require 'hammer_cli_csv/host_collections'
|
29
|
+
require 'hammer_cli_csv/hosts'
|
30
|
+
require 'hammer_cli_csv/import'
|
31
|
+
require 'hammer_cli_csv/installation_medias'
|
32
|
+
require 'hammer_cli_csv/lifecycle_environments'
|
33
|
+
require 'hammer_cli_csv/locations'
|
34
|
+
require 'hammer_cli_csv/operating_systems'
|
35
|
+
require 'hammer_cli_csv/organizations'
|
36
|
+
require 'hammer_cli_csv/partition_tables'
|
37
|
+
require 'hammer_cli_csv/products'
|
38
|
+
require 'hammer_cli_csv/provisioning_templates'
|
39
|
+
require 'hammer_cli_csv/puppet_environments'
|
40
|
+
require 'hammer_cli_csv/puppet_facts'
|
41
|
+
require 'hammer_cli_csv/puppet_reports'
|
42
|
+
require 'hammer_cli_csv/reports'
|
43
|
+
require 'hammer_cli_csv/roles'
|
44
|
+
require 'hammer_cli_csv/smart_proxies'
|
45
|
+
require 'hammer_cli_csv/subnets'
|
46
|
+
require 'hammer_cli_csv/subscriptions'
|
47
|
+
require 'hammer_cli_csv/users'
|
48
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
# Copyright 2013-2014 Red Hat, Inc.
|
2
|
+
#
|
3
|
+
# This software is licensed to you under the GNU General Public
|
4
|
+
# License as published by the Free Software Foundation; either version
|
5
|
+
# 2 of the License (GPLv2) or (at your option) any later version.
|
6
|
+
# There is NO WARRANTY for this software, express or implied,
|
7
|
+
# including the implied warranties of MERCHANTABILITY,
|
8
|
+
# NON-INFRINGEMENT, or FITNESS FOR A PARTICULAR PURPOSE. You should
|
9
|
+
# have received a copy of GPLv2 along with this software; if not, see
|
10
|
+
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
|
11
|
+
|
12
|
+
module HammerCLICsv
|
13
|
+
class CsvCommand
|
14
|
+
class ActivationKeysCommand < BaseCommand
|
15
|
+
command_name 'activation-keys'
|
16
|
+
desc 'import or export activation keys'
|
17
|
+
|
18
|
+
ORGANIZATION = 'Organization'
|
19
|
+
DESCRIPTION = 'Description'
|
20
|
+
LIMIT = 'Limit'
|
21
|
+
ENVIRONMENT = 'Environment'
|
22
|
+
CONTENTVIEW = 'Content View'
|
23
|
+
SYSTEMGROUPS = 'System Groups'
|
24
|
+
SUBSCRIPTIONS = 'Subscriptions'
|
25
|
+
|
26
|
+
def export
|
27
|
+
CSV.open(option_csv_file || '/dev/stdout', 'wb', {:force_quotes => false}) do |csv|
|
28
|
+
csv << [NAME, COUNT, ORGANIZATION, DESCRIPTION, LIMIT, ENVIRONMENT, CONTENTVIEW,
|
29
|
+
SYSTEMGROUPS, SUBSCRIPTIONS]
|
30
|
+
@api.resource(:organizations)
|
31
|
+
.call(:index, {
|
32
|
+
:per_page => 999999
|
33
|
+
})['results'].each do |organization|
|
34
|
+
@api.resource(:activation_keys)
|
35
|
+
.call(:index, {
|
36
|
+
'per_page' => 999999,
|
37
|
+
'organization_id' => organization['id']
|
38
|
+
})['results'].each do |activationkey|
|
39
|
+
puts "Writing activation key '#{activationkey['name']}'" if option_verbose?
|
40
|
+
name = namify(activationkey['name'])
|
41
|
+
count = 1
|
42
|
+
description = activationkey['description']
|
43
|
+
limit = activationkey['usage_limit'].to_i < 0 ? 'Unlimited' : sytemgroup['usage_limit']
|
44
|
+
environment = activationkey['environment']['label']
|
45
|
+
contentview = activationkey['content_view']['name']
|
46
|
+
hostcollections = export_column(activationkey, 'systemGroups', 'name')
|
47
|
+
subscriptions = CSV.generate do |column|
|
48
|
+
column << @api.resource(:subscriptions).call(:index, {
|
49
|
+
'activation_key_id' => activationkey['id']
|
50
|
+
})['results'].collect do |subscription|
|
51
|
+
amount = subscription['amount'] == 0 ? 'Automatic' : subscription['amount']
|
52
|
+
"#{amount}|#{subscription['product_name']}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
subscriptions.delete!("\n")
|
56
|
+
csv << [name, count, organization['label'], description, limit, environment, contentview,
|
57
|
+
hostcollections, subscriptions]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def import
|
64
|
+
@existing = {}
|
65
|
+
|
66
|
+
thread_import do |line|
|
67
|
+
create_activationkeys_from_csv(line)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def create_activationkeys_from_csv(line)
|
72
|
+
if !@existing[line[ORGANIZATION]]
|
73
|
+
@existing[line[ORGANIZATION]] = {}
|
74
|
+
@api.resource(:activation_keys)
|
75
|
+
.call(:index, {
|
76
|
+
'per_page' => 999999,
|
77
|
+
'organization_id' => foreman_organization(:name => line[ORGANIZATION])
|
78
|
+
})['results'].each do |activationkey|
|
79
|
+
@existing[line[ORGANIZATION]][activationkey['name']] = activationkey['id'] if activationkey
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
line[COUNT].to_i.times do |number|
|
84
|
+
name = namify(line[NAME], number)
|
85
|
+
|
86
|
+
if !@existing[line[ORGANIZATION]].include? name
|
87
|
+
print "Creating activation key '#{name}'..." if option_verbose?
|
88
|
+
activationkey = @api.resource(:activation_keys)
|
89
|
+
.call(:create, {
|
90
|
+
'name' => name,
|
91
|
+
'environment_id' => lifecycle_environment(line[ORGANIZATION],
|
92
|
+
:name => line[ENVIRONMENT]),
|
93
|
+
'content_view_id' => katello_contentview(line[ORGANIZATION],
|
94
|
+
:name => line[CONTENTVIEW]),
|
95
|
+
'description' => line[DESCRIPTION],
|
96
|
+
'usage_limit' => usage_limit(line[LIMIT])
|
97
|
+
})
|
98
|
+
@existing[line[ORGANIZATION]][activationkey['name']] = activationkey['id']
|
99
|
+
else
|
100
|
+
print "Updating activation key '#{name}'..." if option_verbose?
|
101
|
+
activationkey = @api.resource(:activation_keys)
|
102
|
+
.call(:update, {
|
103
|
+
'id' => @existing[line[ORGANIZATION]][name],
|
104
|
+
'name' => name,
|
105
|
+
'environment_id' => lifecycle_environment(line[ORGANIZATION],
|
106
|
+
:name => line[ENVIRONMENT]),
|
107
|
+
'content_view_id' => katello_contentview(line[ORGANIZATION],
|
108
|
+
:name => line[CONTENTVIEW]),
|
109
|
+
'description' => line[DESCRIPTION],
|
110
|
+
'usage_limit' => usage_limit(line[LIMIT])
|
111
|
+
})
|
112
|
+
end
|
113
|
+
|
114
|
+
update_subscriptions(activationkey, line)
|
115
|
+
update_groups(activationkey, line)
|
116
|
+
|
117
|
+
puts 'done' if option_verbose?
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def update_groups(activationkey, line)
|
122
|
+
if line[SYSTEMGROUPS] && line[SYSTEMGROUPS] != ''
|
123
|
+
# TODO: note that existing system groups are not removed
|
124
|
+
CSV.parse_line(line[SYSTEMGROUPS], {:skip_blanks => true}).each do |name|
|
125
|
+
@api.resource(:host_collections)
|
126
|
+
.call(:add_activation_keys, {
|
127
|
+
'id' => katello_hostcollection(line[ORGANIZATION], :name => name),
|
128
|
+
'activation_key_ids' => [activationkey['id']]
|
129
|
+
})
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def update_subscriptions(activationkey, line)
|
135
|
+
if line[SUBSCRIPTIONS] && line[SUBSCRIPTIONS] != ''
|
136
|
+
subscriptions = CSV.parse_line(line[SUBSCRIPTIONS], {:skip_blanks => true}).collect do |subscription_details|
|
137
|
+
(amount, name) = subscription_details.split('|')
|
138
|
+
{
|
139
|
+
:id => katello_subscription(line[ORGANIZATION], :name => name),
|
140
|
+
:quantity => amount
|
141
|
+
}
|
142
|
+
end
|
143
|
+
|
144
|
+
# TODO: should there be a destroy_all similar to systems?
|
145
|
+
@api.resource(:subscriptions)
|
146
|
+
.call(:index, {
|
147
|
+
'per_page' => 999999,
|
148
|
+
'activation_key_id' => activationkey['id']
|
149
|
+
})['results'].each do |subscription|
|
150
|
+
@api.resource(:subscriptions)
|
151
|
+
.call(:destroy, {
|
152
|
+
'id' => subscription['id'],
|
153
|
+
'activation_key_id' => activationkey['id']
|
154
|
+
})
|
155
|
+
end
|
156
|
+
|
157
|
+
@api.resource(:subscriptions)
|
158
|
+
.call(:create, {
|
159
|
+
'activation_key_id' => activationkey['id'],
|
160
|
+
'subscriptions' => subscriptions
|
161
|
+
})
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def usage_limit(limit)
|
166
|
+
Integer(limit) rescue -1
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# Copyright 2013-2014 Red Hat, Inc.
|
2
|
+
#
|
3
|
+
# This software is licensed to you under the GNU General Public
|
4
|
+
# License as published by the Free Software Foundation; either version
|
5
|
+
# 2 of the License (GPLv2) or (at your option) any later version.
|
6
|
+
# There is NO WARRANTY for this software, express or implied,
|
7
|
+
# including the implied warranties of MERCHANTABILITY,
|
8
|
+
# NON-INFRINGEMENT, or FITNESS FOR A PARTICULAR PURPOSE. You should
|
9
|
+
# have received a copy of GPLv2 along with this software; if not, see
|
10
|
+
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
|
11
|
+
|
12
|
+
#
|
13
|
+
# -= Architectures CSV =-
|
14
|
+
#
|
15
|
+
# Columns
|
16
|
+
# Name
|
17
|
+
# - Architecture 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
|
+
#
|
23
|
+
|
24
|
+
require 'hammer_cli'
|
25
|
+
require 'json'
|
26
|
+
require 'csv'
|
27
|
+
|
28
|
+
module HammerCLICsv
|
29
|
+
class CsvCommand
|
30
|
+
class ArchitecturesCommand < BaseCommand
|
31
|
+
command_name 'architectures'
|
32
|
+
desc 'import or export architectures'
|
33
|
+
|
34
|
+
OPERATINGSYSTEMS = 'Operating Systems'
|
35
|
+
|
36
|
+
def export
|
37
|
+
CSV.open(option_csv_file || '/dev/stdout', 'wb', {:force_quotes => true}) do |csv|
|
38
|
+
csv << [NAME, COUNT, ORGANIZATIONS, OPERATINGSYSTEMS]
|
39
|
+
@api.resource(:architectures).call(:index, {:per_page => 999999})['results'].each do |architecture|
|
40
|
+
name = architecture['name']
|
41
|
+
count = 1
|
42
|
+
# TODO: http://projects.theforeman.org/issues/4198
|
43
|
+
#operatingsystems = architecture['operatingsystem_ids'].collect do |operatingsystem_id|
|
44
|
+
# foreman_operatingsystem(:id => operatingsystem_id)
|
45
|
+
#end.join(',')
|
46
|
+
operatingsystems = ''
|
47
|
+
csv << [name, count, operatingsystems]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def import
|
53
|
+
@existing = {}
|
54
|
+
@api.resource(:architectures).call(:index, {:per_page => 999999})['results'].each do |architecture|
|
55
|
+
@existing[architecture['name']] = architecture['id'] if architecture
|
56
|
+
end
|
57
|
+
|
58
|
+
thread_import do |line|
|
59
|
+
create_architectures_from_csv(line)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_architectures_from_csv(line)
|
64
|
+
line[COUNT].to_i.times do |number|
|
65
|
+
name = namify(line[NAME], number)
|
66
|
+
architecture_id = @existing[name]
|
67
|
+
operatingsystem_ids = CSV.parse_line(line[OPERATINGSYSTEMS]).collect do |operatingsystem_name|
|
68
|
+
foreman_operatingsystem(:name => operatingsystem_name)
|
69
|
+
end
|
70
|
+
if !architecture_id
|
71
|
+
print "Creating architecture '#{name}'..." if option_verbose?
|
72
|
+
architecture_id = @api.resource(:architectures).call(:create, {
|
73
|
+
'architecture' => {
|
74
|
+
'name' => name,
|
75
|
+
'operatingsystem_ids' => operatingsystem_ids
|
76
|
+
}
|
77
|
+
})
|
78
|
+
else
|
79
|
+
print "Updating architecture '#{name}'..." if option_verbose?
|
80
|
+
@api.resource(:architectures).call(:update, {
|
81
|
+
'id' => architecture_id,
|
82
|
+
'architecture' => {
|
83
|
+
'name' => name,
|
84
|
+
'operatingsystem_ids' => operatingsystem_ids
|
85
|
+
}
|
86
|
+
})
|
87
|
+
end
|
88
|
+
print "done\n" if option_verbose?
|
89
|
+
end
|
90
|
+
rescue RuntimeError => e
|
91
|
+
raise "#{e}\n #{line}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,706 @@
|
|
1
|
+
# Copyright 2013-2014 Red Hat, Inc.
|
2
|
+
#
|
3
|
+
# This software is licensed to you under the GNU General Public
|
4
|
+
# License as published by the Free Software Foundation; either version
|
5
|
+
# 2 of the License (GPLv2) or (at your option) any later version.
|
6
|
+
# There is NO WARRANTY for this software, express or implied,
|
7
|
+
# including the implied warranties of MERCHANTABILITY,
|
8
|
+
# NON-INFRINGEMENT, or FITNESS FOR A PARTICULAR PURPOSE. You should
|
9
|
+
# have received a copy of GPLv2 along with this software; if not, see
|
10
|
+
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
|
11
|
+
|
12
|
+
require 'apipie-bindings'
|
13
|
+
require 'hammer_cli'
|
14
|
+
require 'json'
|
15
|
+
require 'csv'
|
16
|
+
require 'hammer_cli_csv/csv'
|
17
|
+
|
18
|
+
module HammerCLICsv
|
19
|
+
class BaseCommand < HammerCLI::Apipie::Command
|
20
|
+
option %w(-v --verbose), :flag, 'be verbose'
|
21
|
+
option %w(--threads), 'THREAD_COUNT', 'Number of threads to hammer with', :default => 1
|
22
|
+
option %w(--csv-export), :flag, 'Export current data instead of importing'
|
23
|
+
option %w(--csv-file), 'FILE_NAME', 'CSV file (default to /dev/stdout with --csv-export, otherwise required)'
|
24
|
+
option %w(--prefix), 'PREFIX', 'Prefix for all name columns'
|
25
|
+
option %w(--server), 'SERVER', 'Server URL'
|
26
|
+
option %w(-u --username), 'USERNAME', 'Username to access server'
|
27
|
+
option %w(-p --password), 'PASSWORD', 'Password to access server'
|
28
|
+
|
29
|
+
NAME = 'Name'
|
30
|
+
COUNT = 'Count'
|
31
|
+
|
32
|
+
def execute
|
33
|
+
if !option_csv_file
|
34
|
+
if option_csv_export?
|
35
|
+
# rubocop:disable UselessAssignment
|
36
|
+
option_csv_file = '/dev/stdout'
|
37
|
+
else
|
38
|
+
# rubocop:disable UselessAssignment
|
39
|
+
option_csv_file = '/dev/stdin'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
@api = ApipieBindings::API.new({
|
44
|
+
:uri => option_server || HammerCLI::Settings.get(:csv, :host),
|
45
|
+
:username => option_username || HammerCLI::Settings.get(:csv, :username),
|
46
|
+
:password => option_password || HammerCLI::Settings.get(:csv, :password),
|
47
|
+
:api_version => 2
|
48
|
+
})
|
49
|
+
|
50
|
+
option_csv_export? ? export : import
|
51
|
+
HammerCLI::EX_OK
|
52
|
+
end
|
53
|
+
|
54
|
+
def namify(name_format, number = 0)
|
55
|
+
if name_format.index('%')
|
56
|
+
name = name_format % number
|
57
|
+
else
|
58
|
+
name = name_format
|
59
|
+
end
|
60
|
+
name = "#{option_prefix}#{name}" if option_prefix
|
61
|
+
name
|
62
|
+
end
|
63
|
+
|
64
|
+
def labelize(name)
|
65
|
+
name.gsub(/[^a-z0-9\-_]/i, '_')
|
66
|
+
end
|
67
|
+
|
68
|
+
def thread_import(return_headers = false)
|
69
|
+
csv = []
|
70
|
+
CSV.foreach(option_csv_file || '/dev/stdin', {
|
71
|
+
:skip_blanks => true,
|
72
|
+
:headers => :first_row,
|
73
|
+
:return_headers => return_headers
|
74
|
+
}) do |line|
|
75
|
+
csv << line
|
76
|
+
end
|
77
|
+
lines_per_thread = csv.length / option_threads.to_i + 1
|
78
|
+
splits = []
|
79
|
+
|
80
|
+
option_threads.to_i.times do |current_thread|
|
81
|
+
start_index = ((current_thread) * lines_per_thread).to_i
|
82
|
+
finish_index = ((current_thread + 1) * lines_per_thread).to_i
|
83
|
+
finish_index = csv.length if finish_index > csv.length
|
84
|
+
if start_index <= finish_index
|
85
|
+
lines = csv[start_index...finish_index].clone
|
86
|
+
splits << Thread.new do
|
87
|
+
lines.each do |line|
|
88
|
+
if line[NAME][0] != '#'
|
89
|
+
yield line
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
splits.each do |thread|
|
97
|
+
thread.join
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def hammer_context
|
102
|
+
{
|
103
|
+
:interactive => false,
|
104
|
+
:username => 'admin', # TODO: this needs to come from config/settings
|
105
|
+
:password => 'changeme' # TODO: this needs to come from config/settings
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
def hammer(context = nil)
|
110
|
+
HammerCLI::MainCommand.new('', context || hammer_context)
|
111
|
+
end
|
112
|
+
|
113
|
+
def foreman_organization(options = {})
|
114
|
+
@organizations ||= {}
|
115
|
+
|
116
|
+
if options[:name]
|
117
|
+
return nil if options[:name].nil? || options[:name].empty?
|
118
|
+
options[:id] = @organizations[options[:name]]
|
119
|
+
if !options[:id]
|
120
|
+
organization = @api.resource(:organizations).call(:index, {
|
121
|
+
:per_page => 999999,
|
122
|
+
'search' => "name=\"#{options[:name]}\""
|
123
|
+
})['results']
|
124
|
+
raise "Organization '#{options[:name]}' not found" if !organization || organization.empty?
|
125
|
+
options[:id] = organization[0]['id']
|
126
|
+
@organizations[options[:name]] = options[:id]
|
127
|
+
end
|
128
|
+
result = options[:id]
|
129
|
+
else
|
130
|
+
return nil if options[:id].nil?
|
131
|
+
options[:name] = @organizations.key(options[:id])
|
132
|
+
if !options[:name]
|
133
|
+
organization = @api.resource(:organizations).call(:show, {'id' => options[:id]})
|
134
|
+
raise "Organization 'id=#{options[:id]}' not found" if !organization || organization.empty?
|
135
|
+
options[:name] = organization['name']
|
136
|
+
@organizations[options[:name]] = options[:id]
|
137
|
+
end
|
138
|
+
result = options[:name]
|
139
|
+
end
|
140
|
+
|
141
|
+
result
|
142
|
+
end
|
143
|
+
|
144
|
+
def foreman_location(options = {})
|
145
|
+
@locations ||= {}
|
146
|
+
|
147
|
+
if options[:name]
|
148
|
+
return nil if options[:name].nil? || options[:name].empty?
|
149
|
+
options[:id] = @locations[options[:name]]
|
150
|
+
if !options[:id]
|
151
|
+
location = @api.resource(:locations).call(:index, {
|
152
|
+
:per_page => 999999,
|
153
|
+
'search' => "name=\"#{options[:name]}\""
|
154
|
+
})['results']
|
155
|
+
raise "Location '#{options[:name]}' not found" if !location || location.empty?
|
156
|
+
options[:id] = location[0]['id']
|
157
|
+
@locations[options[:name]] = options[:id]
|
158
|
+
end
|
159
|
+
result = options[:id]
|
160
|
+
else
|
161
|
+
return nil if options[:id].nil?
|
162
|
+
options[:name] = @locations.key(options[:id])
|
163
|
+
if !options[:name]
|
164
|
+
location = @api.resource(:locations).call(:show, {'id' => options[:id]})
|
165
|
+
raise "Location 'id=#{options[:id]}' not found" if !location || location.empty?
|
166
|
+
options[:name] = location['name']
|
167
|
+
@locations[options[:name]] = options[:id]
|
168
|
+
end
|
169
|
+
result = options[:name]
|
170
|
+
end
|
171
|
+
|
172
|
+
result
|
173
|
+
end
|
174
|
+
|
175
|
+
def foreman_role(options = {})
|
176
|
+
@roles ||= {}
|
177
|
+
|
178
|
+
if options[:name]
|
179
|
+
return nil if options[:name].nil? || options[:name].empty?
|
180
|
+
options[:id] = @roles[options[:name]]
|
181
|
+
if !options[:id]
|
182
|
+
role = @api.resource(:roles).call(:index, {
|
183
|
+
:per_page => 999999,
|
184
|
+
'search' => "name=\"#{options[:name]}\""
|
185
|
+
})['results']
|
186
|
+
raise "Role '#{options[:name]}' not found" if !role || role.empty?
|
187
|
+
options[:id] = role[0]['id']
|
188
|
+
@roles[options[:name]] = options[:id]
|
189
|
+
end
|
190
|
+
result = options[:id]
|
191
|
+
else
|
192
|
+
return nil if options[:id].nil?
|
193
|
+
options[:name] = @roles.key(options[:id])
|
194
|
+
if !options[:name]
|
195
|
+
role = @api.resource(:roles).call(:show, {'id' => options[:id]})
|
196
|
+
raise "Role 'id=#{options[:id]}' not found" if !role || role.empty?
|
197
|
+
options[:name] = role['name']
|
198
|
+
@roles[options[:name]] = options[:id]
|
199
|
+
end
|
200
|
+
result = options[:name]
|
201
|
+
end
|
202
|
+
|
203
|
+
result
|
204
|
+
end
|
205
|
+
|
206
|
+
def foreman_permission(options = {})
|
207
|
+
@permissions ||= {}
|
208
|
+
|
209
|
+
if options[:name]
|
210
|
+
return nil if options[:name].nil? || options[:name].empty?
|
211
|
+
options[:id] = @permissions[options[:name]]
|
212
|
+
if !options[:id]
|
213
|
+
permission = @api.resource(:permissions).call(:index, {
|
214
|
+
:per_page => 999999,
|
215
|
+
'name' => options[:name]
|
216
|
+
})['results']
|
217
|
+
raise "Permission '#{options[:name]}' not found" if !permission || permission.empty?
|
218
|
+
options[:id] = permission[0]['id']
|
219
|
+
@permissions[options[:name]] = options[:id]
|
220
|
+
end
|
221
|
+
result = options[:id]
|
222
|
+
else
|
223
|
+
return nil if options[:id].nil?
|
224
|
+
options[:name] = @permissions.key(options[:id])
|
225
|
+
if !options[:name]
|
226
|
+
permission = @api.resource(:permissions).call(:show, {'id' => options[:id]})
|
227
|
+
raise "Permission 'id=#{options[:id]}' not found" if !permission || permission.empty?
|
228
|
+
options[:name] = permission['name']
|
229
|
+
@permissions[options[:name]] = options[:id]
|
230
|
+
end
|
231
|
+
result = options[:name]
|
232
|
+
end
|
233
|
+
|
234
|
+
result
|
235
|
+
end
|
236
|
+
|
237
|
+
def foreman_filter(role, resource, search)
|
238
|
+
search = nil if search && search.empty?
|
239
|
+
filters = @api.resource(:filters).call(:index, {
|
240
|
+
:per_page => 999999,
|
241
|
+
'search' => "role=\"#{role}\""
|
242
|
+
})['results']
|
243
|
+
filters.each do |filter|
|
244
|
+
return filter['id'] if filter['resource_type'] == resource && filter['search'] == search
|
245
|
+
end
|
246
|
+
|
247
|
+
nil
|
248
|
+
end
|
249
|
+
|
250
|
+
def foreman_environment(options = {})
|
251
|
+
@environments ||= {}
|
252
|
+
|
253
|
+
if options[:name]
|
254
|
+
return nil if options[:name].nil? || options[:name].empty?
|
255
|
+
options[:id] = @environments[options[:name]]
|
256
|
+
if !options[:id]
|
257
|
+
environment = @api.resource(:environments).call(:index, {
|
258
|
+
:per_page => 999999,
|
259
|
+
'search' => "name=\"#{ options[:name] }\""
|
260
|
+
})['results']
|
261
|
+
raise "Puppet environment '#{options[:name]}' not found" if !environment || environment.empty?
|
262
|
+
options[:id] = environment[0]['id']
|
263
|
+
@environments[options[:name]] = options[:id]
|
264
|
+
end
|
265
|
+
result = options[:id]
|
266
|
+
else
|
267
|
+
return nil if options[:id].nil?
|
268
|
+
options[:name] = @environments.key(options[:id])
|
269
|
+
if !options[:name]
|
270
|
+
environment = @api.resource(:environments).call(:show, {'id' => options[:id]})
|
271
|
+
raise "Puppet environment '#{options[:name]}' not found" if !environment || environment.empty?
|
272
|
+
options[:name] = environment['name']
|
273
|
+
@environments[options[:name]] = options[:id]
|
274
|
+
end
|
275
|
+
result = options[:name]
|
276
|
+
end
|
277
|
+
|
278
|
+
result
|
279
|
+
end
|
280
|
+
|
281
|
+
def foreman_template_kind(options = {})
|
282
|
+
@template_kinds ||= {}
|
283
|
+
|
284
|
+
if options[:name]
|
285
|
+
return nil if options[:name].nil? || options[:name].empty?
|
286
|
+
options[:id] = @template_kinds[options[:name]]
|
287
|
+
if !options[:id]
|
288
|
+
template_kind = @api.resource(:template_kinds).call(:index, {
|
289
|
+
:per_page => 999999,
|
290
|
+
'search' => "name=\"#{options[:name]}\""
|
291
|
+
})['results']
|
292
|
+
raise "Template kind '#{options[:name]}' not found" if !template_kind || template_kind.empty?
|
293
|
+
options[:id] = template_kind[0]['id']
|
294
|
+
@template_kinds[options[:name]] = options[:id]
|
295
|
+
end
|
296
|
+
result = options[:id]
|
297
|
+
else
|
298
|
+
return nil if options[:id].nil?
|
299
|
+
options[:name] = @template_kinds.key(options[:id])
|
300
|
+
if !options[:name]
|
301
|
+
template_kind = @api.resource(:template_kinds).call(:show, {'id' => options[:id]})
|
302
|
+
raise "Template kind 'id=#{options[:id]}' not found" if !template_kind || template_kind.empty?
|
303
|
+
options[:name] = template_kind['name']
|
304
|
+
@template_kinds[options[:name]] = options[:id]
|
305
|
+
end
|
306
|
+
result = options[:name]
|
307
|
+
end
|
308
|
+
|
309
|
+
result
|
310
|
+
end
|
311
|
+
|
312
|
+
def foreman_operatingsystem(options = {})
|
313
|
+
@operatingsystems ||= {}
|
314
|
+
|
315
|
+
if options[:name]
|
316
|
+
return nil if options[:name].nil? || options[:name].empty?
|
317
|
+
options[:id] = @operatingsystems[options[:name]]
|
318
|
+
if !options[:id]
|
319
|
+
(osname, major, minor) = split_os_name(options[:name])
|
320
|
+
search = "name=\"#{osname}\" and major=\"#{major}\" and minor=\"#{minor}\""
|
321
|
+
operatingsystems = @api.resource(:operatingsystems).call(:index, {
|
322
|
+
:per_page => 999999,
|
323
|
+
'search' => search
|
324
|
+
})['results']
|
325
|
+
operatingsystem = operatingsystems[0]
|
326
|
+
raise "Operating system '#{options[:name]}' not found" if !operatingsystem || operatingsystem.empty?
|
327
|
+
options[:id] = operatingsystem['id']
|
328
|
+
@operatingsystems[options[:name]] = options[:id]
|
329
|
+
end
|
330
|
+
result = options[:id]
|
331
|
+
else
|
332
|
+
return nil if options[:id].nil?
|
333
|
+
options[:name] = @operatingsystems.key(options[:id])
|
334
|
+
if !options[:name]
|
335
|
+
operatingsystem = @api.resource(:operatingsystems).call(:show, {'id' => options[:id]})
|
336
|
+
raise "Operating system 'id=#{options[:id]}' not found" if !operatingsystem || operatingsystem.empty?
|
337
|
+
options[:name] = build_os_name(operatingsystem['name'],
|
338
|
+
operatingsystem['major'],
|
339
|
+
operatingsystem['minor'])
|
340
|
+
@operatingsystems[options[:name]] = options[:id]
|
341
|
+
end
|
342
|
+
result = options[:name]
|
343
|
+
end
|
344
|
+
|
345
|
+
result
|
346
|
+
end
|
347
|
+
|
348
|
+
def foreman_architecture(options = {})
|
349
|
+
@architectures ||= {}
|
350
|
+
|
351
|
+
if options[:name]
|
352
|
+
return nil if options[:name].nil? || options[:name].empty?
|
353
|
+
options[:id] = @architectures[options[:name]]
|
354
|
+
if !options[:id]
|
355
|
+
architecture = @api.resource(:architectures).call(:index, {
|
356
|
+
:per_page => 999999,
|
357
|
+
'search' => "name=\"#{options[:name]}\""
|
358
|
+
})['results']
|
359
|
+
raise "Architecture '#{options[:name]}' not found" if !architecture || architecture.empty?
|
360
|
+
options[:id] = architecture[0]['id']
|
361
|
+
@architectures[options[:name]] = options[:id]
|
362
|
+
end
|
363
|
+
result = options[:id]
|
364
|
+
else
|
365
|
+
return nil if options[:id].nil?
|
366
|
+
options[:name] = @architectures.key(options[:id])
|
367
|
+
if !options[:name]
|
368
|
+
architecture = @api.resource(:architectures).call(:show, {'id' => options[:id]})
|
369
|
+
raise "Architecture 'id=#{options[:id]}' not found" if !architecture || architecture.empty?
|
370
|
+
options[:name] = architecture['name']
|
371
|
+
@architectures[options[:name]] = options[:id]
|
372
|
+
end
|
373
|
+
result = options[:name]
|
374
|
+
end
|
375
|
+
|
376
|
+
result
|
377
|
+
end
|
378
|
+
|
379
|
+
def foreman_domain(options = {})
|
380
|
+
@domains ||= {}
|
381
|
+
|
382
|
+
if options[:name]
|
383
|
+
return nil if options[:name].nil? || options[:name].empty?
|
384
|
+
options[:id] = @domains[options[:name]]
|
385
|
+
if !options[:id]
|
386
|
+
domain = @api.resource(:domains).call(:index, {
|
387
|
+
:per_page => 999999,
|
388
|
+
'search' => "name=\"#{options[:name]}\""
|
389
|
+
})['results']
|
390
|
+
raise "Domain '#{options[:name]}' not found" if !domain || domain.empty?
|
391
|
+
options[:id] = domain[0]['id']
|
392
|
+
@domains[options[:name]] = options[:id]
|
393
|
+
end
|
394
|
+
result = options[:id]
|
395
|
+
else
|
396
|
+
return nil if options[:id].nil?
|
397
|
+
options[:name] = @domains.key(options[:id])
|
398
|
+
if !options[:name]
|
399
|
+
domain = @api.resource(:domains).call(:show, {'id' => options[:id]})
|
400
|
+
raise "Domain 'id=#{options[:id]}' not found" if !domain || domain.empty?
|
401
|
+
options[:name] = domain['name']
|
402
|
+
@domains[options[:name]] = options[:id]
|
403
|
+
end
|
404
|
+
result = options[:name]
|
405
|
+
end
|
406
|
+
|
407
|
+
result
|
408
|
+
end
|
409
|
+
|
410
|
+
def foreman_partitiontable(options = {})
|
411
|
+
@ptables ||= {}
|
412
|
+
|
413
|
+
if options[:name]
|
414
|
+
return nil if options[:name].nil? || options[:name].empty?
|
415
|
+
options[:id] = @ptables[options[:name]]
|
416
|
+
if !options[:id]
|
417
|
+
ptable = @api.resource(:ptables).call(:index, {
|
418
|
+
:per_page => 999999,
|
419
|
+
'search' => "name=\"#{options[:name]}\""
|
420
|
+
})['results']
|
421
|
+
raise "Partition table '#{options[:name]}' not found" if !ptable || ptable.empty?
|
422
|
+
options[:id] = ptable[0]['id']
|
423
|
+
@ptables[options[:name]] = options[:id]
|
424
|
+
end
|
425
|
+
result = options[:id]
|
426
|
+
elsif options[:id]
|
427
|
+
return nil if options[:id].nil?
|
428
|
+
options[:name] = @ptables.key(options[:id])
|
429
|
+
if !options[:name]
|
430
|
+
ptable = @api.resource(:ptables).call(:show, {'id' => options[:id]})
|
431
|
+
options[:name] = ptable['name']
|
432
|
+
@ptables[options[:name]] = options[:id]
|
433
|
+
end
|
434
|
+
result = options[:name]
|
435
|
+
elsif !options[:name] && !options[:id]
|
436
|
+
result = ''
|
437
|
+
end
|
438
|
+
|
439
|
+
result
|
440
|
+
end
|
441
|
+
|
442
|
+
def lifecycle_environment(organization, options = {})
|
443
|
+
@lifecycle_environments ||= {}
|
444
|
+
@lifecycle_environments[organization] ||= {
|
445
|
+
}
|
446
|
+
|
447
|
+
if options[:name]
|
448
|
+
return nil if options[:name].nil? || options[:name].empty?
|
449
|
+
options[:id] = @lifecycle_environments[organization][options[:name]]
|
450
|
+
if !options[:id]
|
451
|
+
@api.resource(:lifecycle_environments)
|
452
|
+
.call(:index, {
|
453
|
+
:per_page => 999999,
|
454
|
+
'organization_id' => foreman_organization(:name => organization)
|
455
|
+
})['results'].each do |environment|
|
456
|
+
@lifecycle_environments[organization][environment['name']] = environment['id']
|
457
|
+
end
|
458
|
+
options[:id] = @lifecycle_environments[organization][options[:name]]
|
459
|
+
raise "Lifecycle environment '#{options[:name]}' not found" if !options[:id]
|
460
|
+
end
|
461
|
+
result = options[:id]
|
462
|
+
else
|
463
|
+
return nil if options[:id].nil?
|
464
|
+
options[:name] = @lifecycle_environments.key(options[:id])
|
465
|
+
if !options[:name]
|
466
|
+
environment = @api.resource(:lifecycle_environments).call(:show, {'id' => options[:id]})
|
467
|
+
raise "Lifecycle environment '#{options[:name]}' not found" if !environment || environment.empty?
|
468
|
+
options[:name] = environment['name']
|
469
|
+
@lifecycle_environments[options[:name]] = options[:id]
|
470
|
+
end
|
471
|
+
result = options[:name]
|
472
|
+
end
|
473
|
+
|
474
|
+
result
|
475
|
+
end
|
476
|
+
|
477
|
+
def katello_contentview(organization, options = {})
|
478
|
+
@contentviews ||= {}
|
479
|
+
@contentviews[organization] ||= {}
|
480
|
+
|
481
|
+
if options[:name]
|
482
|
+
return nil if options[:name].nil? || options[:name].empty?
|
483
|
+
options[:id] = @contentviews[organization][options[:name]]
|
484
|
+
if !options[:id]
|
485
|
+
@api.resource(:content_views).call(:index, {
|
486
|
+
:per_page => 999999,
|
487
|
+
'organization_id' => foreman_organization(:name => organization)
|
488
|
+
})['results'].each do |contentview|
|
489
|
+
@contentviews[organization][contentview['name']] = contentview['id']
|
490
|
+
end
|
491
|
+
options[:id] = @contentviews[organization][options[:name]]
|
492
|
+
raise "Content view '#{options[:name]}' not found" if !options[:id]
|
493
|
+
end
|
494
|
+
result = options[:id]
|
495
|
+
else
|
496
|
+
return nil if options[:id].nil?
|
497
|
+
options[:name] = @contentviews.key(options[:id])
|
498
|
+
if !options[:name]
|
499
|
+
contentview = @api.resource(:content_views).call(:show, {'id' => options[:id]})
|
500
|
+
raise "Puppet contentview '#{options[:name]}' not found" if !contentview || contentview.empty?
|
501
|
+
options[:name] = contentview['name']
|
502
|
+
@contentviews[options[:name]] = options[:id]
|
503
|
+
end
|
504
|
+
result = options[:name]
|
505
|
+
end
|
506
|
+
|
507
|
+
result
|
508
|
+
end
|
509
|
+
|
510
|
+
def katello_repository(organization, options = {})
|
511
|
+
@repositories ||= {}
|
512
|
+
@repositories[organization] ||= {}
|
513
|
+
|
514
|
+
if options[:name]
|
515
|
+
return nil if options[:name].nil? || options[:name].empty?
|
516
|
+
options[:id] = @repositories[organization][options[:name]]
|
517
|
+
if !options[:id]
|
518
|
+
@api.resource(:repositories)
|
519
|
+
.call(:index, {
|
520
|
+
:per_page => 999999,
|
521
|
+
'organization_id' => foreman_organization(:name => organization)
|
522
|
+
})['results'].each do |repository|
|
523
|
+
@repositories[organization][repository['name']] = repository['id']
|
524
|
+
end
|
525
|
+
options[:id] = @repositories[organization][options[:name]]
|
526
|
+
raise "Repository '#{options[:name]}' not found" if !options[:id]
|
527
|
+
end
|
528
|
+
result = options[:id]
|
529
|
+
else
|
530
|
+
return nil if options[:id].nil?
|
531
|
+
options[:name] = @repositories.key(options[:id])
|
532
|
+
if !options[:name]
|
533
|
+
repository = @api.resource(:repositories).call(:show, {'id' => options[:id]})
|
534
|
+
raise "Puppet repository '#{options[:name]}' not found" if !repository || repository.empty?
|
535
|
+
options[:name] = repository['name']
|
536
|
+
@repositoriesr[options[:name]] = options[:id]
|
537
|
+
end
|
538
|
+
result = options[:name]
|
539
|
+
end
|
540
|
+
|
541
|
+
result
|
542
|
+
end
|
543
|
+
|
544
|
+
def katello_subscription(organization, options = {})
|
545
|
+
@subscriptions ||= {}
|
546
|
+
@subscriptions[organization] ||= {}
|
547
|
+
|
548
|
+
if options[:name]
|
549
|
+
return nil if options[:name].nil? || options[:name].empty?
|
550
|
+
options[:id] = @subscriptions[organization][options[:name]]
|
551
|
+
if !options[:id]
|
552
|
+
results = @api.resource(:subscriptions).call(:index, {
|
553
|
+
:per_page => 999999,
|
554
|
+
'organization_id' => foreman_organization(:name => organization),
|
555
|
+
'search' => "name:\"#{options[:name]}\""
|
556
|
+
})
|
557
|
+
raise "No subscriptions match '#{options[:name]}'" if results['subtotal'] == 0
|
558
|
+
raise "Too many subscriptions match '#{options[:name]}'" if results['subtotal'] > 1
|
559
|
+
subscription = results['results'][0]
|
560
|
+
@subscriptions[organization][options[:name]] = subscription['id']
|
561
|
+
options[:id] = @subscriptions[organization][options[:name]]
|
562
|
+
raise "Subscription '#{options[:name]}' not found" if !options[:id]
|
563
|
+
end
|
564
|
+
result = options[:id]
|
565
|
+
else
|
566
|
+
return nil if options[:id].nil?
|
567
|
+
options[:name] = @subscriptions.key(options[:id])
|
568
|
+
if !options[:name]
|
569
|
+
subscription = @api.resource(:subscriptions).call(:show, {'id' => options[:id]})
|
570
|
+
raise "Subscription '#{options[:name]}' not found" if !subscription || subscription.empty?
|
571
|
+
options[:name] = subscription['name']
|
572
|
+
@subscriptions[options[:name]] = options[:id]
|
573
|
+
end
|
574
|
+
result = options[:name]
|
575
|
+
end
|
576
|
+
|
577
|
+
result
|
578
|
+
end
|
579
|
+
|
580
|
+
def katello_hostcollection(organization, options = {})
|
581
|
+
@hostcollections ||= {}
|
582
|
+
@hostcollections[organization] ||= {}
|
583
|
+
|
584
|
+
if options[:name]
|
585
|
+
return nil if options[:name].nil? || options[:name].empty?
|
586
|
+
options[:id] = @hostcollections[organization][options[:name]]
|
587
|
+
if !options[:id]
|
588
|
+
@api.resource(:host_collections).call(:index,
|
589
|
+
{
|
590
|
+
:per_page => 999999,
|
591
|
+
'organization_id' => foreman_organization(:name => organization),
|
592
|
+
'search' => "name:\"#{options[:name]}\""
|
593
|
+
})['results'].each do |hostcollection|
|
594
|
+
@hostcollections[organization][hostcollection['name']] = hostcollection['id'] if hostcollection
|
595
|
+
end
|
596
|
+
options[:id] = @hostcollections[organization][options[:name]]
|
597
|
+
raise "System group '#{options[:name]}' not found" if !options[:id]
|
598
|
+
end
|
599
|
+
result = options[:id]
|
600
|
+
else
|
601
|
+
return nil if options[:id].nil?
|
602
|
+
options[:name] = @hostcollections.key(options[:id])
|
603
|
+
if !options[:name]
|
604
|
+
hostcollection = @api.resource(:host_collections).call(:show, {'id' => options[:id]})
|
605
|
+
raise "System group '#{options[:name]}' not found" if !hostcollection || hostcollection.empty?
|
606
|
+
options[:name] = hostcollection['name']
|
607
|
+
@hostcollections[options[:name]] = options[:id]
|
608
|
+
end
|
609
|
+
result = options[:name]
|
610
|
+
end
|
611
|
+
|
612
|
+
result
|
613
|
+
end
|
614
|
+
|
615
|
+
def build_os_name(name, major, minor)
|
616
|
+
name += " #{major}" if major && major != ''
|
617
|
+
name += ".#{minor}" if minor && minor != ''
|
618
|
+
name
|
619
|
+
end
|
620
|
+
|
621
|
+
# "Red Hat 6.4" => "Red Hat", "6", "4"
|
622
|
+
# "Red Hat 6" => "Red Hat", "6", ''
|
623
|
+
def split_os_name(name)
|
624
|
+
tokens = name.split(' ')
|
625
|
+
is_number = Float(tokens[-1]) rescue false
|
626
|
+
if is_number
|
627
|
+
(major, minor) = tokens[-1].split('.').flatten
|
628
|
+
name = tokens[0...-1].join(' ')
|
629
|
+
else
|
630
|
+
name = tokens.join(' ')
|
631
|
+
end
|
632
|
+
[name, major || '', minor || '']
|
633
|
+
end
|
634
|
+
|
635
|
+
def export_column(object, name, field)
|
636
|
+
return '' unless object[name]
|
637
|
+
values = CSV.generate do |column|
|
638
|
+
column << object[name].collect do |fields|
|
639
|
+
fields[field]
|
640
|
+
end
|
641
|
+
end
|
642
|
+
values.delete!("\n")
|
643
|
+
end
|
644
|
+
|
645
|
+
def collect_column(column)
|
646
|
+
return [] if column.nil? || column.empty?
|
647
|
+
CSV.parse_line(column, {:skip_blanks => true}).collect do |value|
|
648
|
+
yield value
|
649
|
+
end
|
650
|
+
end
|
651
|
+
|
652
|
+
def pluralize(name)
|
653
|
+
case name
|
654
|
+
when /smart_proxy/
|
655
|
+
'smart_proxies'
|
656
|
+
else
|
657
|
+
"#{name}s"
|
658
|
+
end
|
659
|
+
end
|
660
|
+
|
661
|
+
def associate_organizations(id, organizations, name)
|
662
|
+
return if organizations.nil?
|
663
|
+
|
664
|
+
associations ||= {}
|
665
|
+
CSV.parse_line(organizations).each do |organization|
|
666
|
+
organization_id = foreman_organization(:name => organization)
|
667
|
+
if associations[organization].nil?
|
668
|
+
associations[organization] = @api.resource(:organizations).call(:show, {'id' => organization_id})[pluralize(name)].collect do |reference_object|
|
669
|
+
reference_object['id']
|
670
|
+
end
|
671
|
+
end
|
672
|
+
associations[organization] += [id] if !associations[organization].include? id
|
673
|
+
@api.resource(:organizations)
|
674
|
+
.call(:update, {
|
675
|
+
'id' => organization_id,
|
676
|
+
'organization' => {
|
677
|
+
"#{name}_ids" => associations[organization]
|
678
|
+
}
|
679
|
+
})
|
680
|
+
end if organizations && !organizations.empty?
|
681
|
+
end
|
682
|
+
|
683
|
+
def associate_locations(id, locations, name)
|
684
|
+
return if locations.nil?
|
685
|
+
|
686
|
+
associations ||= {}
|
687
|
+
CSV.parse_line(locations).each do |location|
|
688
|
+
location_id = foreman_location(:name => location)
|
689
|
+
if associations[location].nil?
|
690
|
+
associations[location] = @api.resource(:locations).call(:show, {'id' => location_id})[pluralize(name)].collect do |reference_object|
|
691
|
+
reference_object['id']
|
692
|
+
end
|
693
|
+
end
|
694
|
+
associations[location] += [id] if !associations[location].include? id
|
695
|
+
|
696
|
+
@api.resource(:locations)
|
697
|
+
.call(:update, {
|
698
|
+
'id' => location_id,
|
699
|
+
'location' => {
|
700
|
+
"#{name}_ids" => associations[location]
|
701
|
+
}
|
702
|
+
})
|
703
|
+
end if locations && !locations.empty?
|
704
|
+
end
|
705
|
+
end
|
706
|
+
end
|