Project

General

Profile

Download (38.1 KB) Statistics
| Branch: | Tag: | Revision:

hammer-cli-csv / lib / hammer_cli_csv / base.rb @ f5d21adb

1 587327f4 Tom McKay
require 'apipie-bindings'
2 3c5469d2 Tom McKay
require 'hammer_cli'
3
require 'json'
4 6f221b51 Tom McKay
require 'open-uri'
5 3c5469d2 Tom McKay
require 'csv'
6 f8ecc788 Tom McKay
require 'hammer_cli_csv/csv'
7 3c5469d2 Tom McKay
8 31c7af0e Tom McKay
# rubocop:disable ClassLength
9 3c5469d2 Tom McKay
module HammerCLICsv
10 587327f4 Tom McKay
  class BaseCommand < HammerCLI::Apipie::Command
11 f5d21adb Tom McKay
    include ::HammerCLICsv::Utils::Config
12
13 8ac78bfe Tom McKay
    option %w(-v --verbose), :flag, 'be verbose'
14 02387fb5 Tom McKay
    option %w(--threads), 'THREAD_COUNT', 'Number of threads to hammer with',
15
           :default => 1, :hidden => true
16 088e0854 Tom McKay
    option %w(--export), :flag, 'Export current data instead of importing'
17 a2eda8bf Tom McKay
    option %w(--file), 'FILE_NAME', 'CSV file (default to /dev/stdout with --export, otherwise required)'
18 b2e88b7c Tom McKay
    option %w(--prefix), 'PREFIX', 'Prefix for all name columns',
19
           :hidden => true
20 088e0854 Tom McKay
    option %w(--organization), 'ORGANIZATION', _('Only process organization matching this name')
21 3fe1ff94 Tom McKay
    option %w(--continue-on-error), :flag, _('Continue processing even if individual resource error')
22 088e0854 Tom McKay
23
    option %w(--csv-file), 'FILE_NAME', 'Option --csv-file is deprecated. Use --file',
24
           :deprecated => "Use --file", :hidden => true,
25
           :attribute_name => :option_file
26
    option %w(--csv-export), :flag, 'Option --csv-export is deprecated. Use --export',
27
           :deprecated => "Use --export", :hidden => true,
28
           :attribute_name => :option_export
29
30 7bea883f Grant Gainey
    NAME = 'Name'
31
    COUNT = 'Count'
32
33 b2e88b7c Tom McKay
    def self.supported?
34
      false
35
    end
36
37
    def supported?
38
      self.class.supported?
39
    end
40
41
    def help
42
      print_message _('**** This command is unsupported and is provided as tech preview. ****') unless supported?
43
      super
44
    end
45
46 1a0abf99 Tom McKay
    def execute
47 f5d21adb Tom McKay
      @api = api_connection
48 1909f2e6 Tom McKay
      @server_status = check_server_status(@server, @username, @password)
49 c2496839 Tom McKay
50 c06f1783 Tom McKay
      if option_export?
51
        if option_file
52
          CSV.open(option_file, 'wb', {:force_quotes => false}) do |csv|
53
            export csv
54
          end
55
        else
56
          CSV do |csv|
57
            export csv
58
          end
59
        end
60
      else
61
        import
62
      end
63 612bf01e Tom McKay
      HammerCLI::EX_OK
64 1a0abf99 Tom McKay
    end
65
66 3e5a297d Tom McKay
    def check_server_status(server, username, password)
67 c2496839 Tom McKay
      url = "#{server}/api/status"
68
      uri = URI(url)
69 2df1e79b Tom McKay
      nethttp = Net::HTTP.new(uri.host, uri.port)
70
      nethttp.use_ssl = uri.scheme == 'https'
71
      nethttp.verify_mode = OpenSSL::SSL::VERIFY_NONE
72
      server_status = nethttp.start do |http|
73 c2496839 Tom McKay
        request = Net::HTTP::Get.new uri.request_uri
74
        request.basic_auth(username, password)
75
        response = http.request(request)
76
        JSON.parse(response.body)
77
      end
78
79 9e11b4c5 Tom McKay
      url = "#{server}/api/v2/plugins"
80
      uri = URI(url)
81
      nethttp = Net::HTTP.new(uri.host, uri.port)
82
      nethttp.use_ssl = uri.scheme == 'https'
83
      nethttp.verify_mode = OpenSSL::SSL::VERIFY_NONE
84
      server_status['plugins'] = nethttp.start do |http|
85
        request = Net::HTTP::Get.new uri.request_uri
86
        request.basic_auth(username, password)
87
        response = http.request(request)
88
        JSON.parse(response.body)['results']
89
      end
90
91 c2496839 Tom McKay
      server_status
92
    end
93
94 8ac78bfe Tom McKay
    def namify(name_format, number = 0)
95 502df2e4 Tom McKay
      return '' unless name_format
96 3c5469d2 Tom McKay
      if name_format.index('%')
97 c1357ce1 Tom McKay
        name = name_format % number
98 3c5469d2 Tom McKay
      else
99 c1357ce1 Tom McKay
        name = name_format
100 3c5469d2 Tom McKay
      end
101 c1357ce1 Tom McKay
      name = "#{option_prefix}#{name}" if option_prefix
102
      name
103 3c5469d2 Tom McKay
    end
104 663c2370 Tom McKay
105 9d9e4494 Tom McKay
    def labelize(name)
106 8ac78bfe Tom McKay
      name.gsub(/[^a-z0-9\-_]/i, '_')
107 9d9e4494 Tom McKay
    end
108
109 e9b4881a Tom McKay
    def thread_import(return_headers = false, filename=nil, name_column=nil)
110 088e0854 Tom McKay
      filename ||= option_file || '/dev/stdin'
111 2be0739f Tom McKay
      csv = []
112 6f221b51 Tom McKay
      CSV.new(open(filename), {
113 e9b4881a Tom McKay
          :skip_blanks => true,
114
          :headers => :first_row,
115
          :return_headers => return_headers
116 6f221b51 Tom McKay
      }).each do |line|
117 2be0739f Tom McKay
        csv << line
118
      end
119 8ac78bfe Tom McKay
      lines_per_thread = csv.length / option_threads.to_i + 1
120 663c2370 Tom McKay
      splits = []
121
122 6bc031bd Tom McKay
      option_threads.to_i.times do |current_thread|
123 663c2370 Tom McKay
        start_index = ((current_thread) * lines_per_thread).to_i
124
        finish_index = ((current_thread + 1) * lines_per_thread).to_i
125 df47dd3c Tom McKay
        finish_index = csv.length if finish_index > csv.length
126
        if start_index <= finish_index
127
          lines = csv[start_index...finish_index].clone
128
          splits << Thread.new do
129
            lines.each do |line|
130 3fe1ff94 Tom McKay
              next if line[name_column || NAME][0] == '#'
131
              begin
132 df47dd3c Tom McKay
                yield line
133 3fe1ff94 Tom McKay
              rescue RuntimeError => e
134
                message = "#{e}\n#{line}"
135 f370cc85 Tom McKay
                option_continue_on_error? ? $stderr.puts(_("Error: %{message}") % {:message => message}) : raise(message)
136 df47dd3c Tom McKay
              end
137 663c2370 Tom McKay
            end
138
          end
139
        end
140
      end
141
142
      splits.each do |thread|
143
        thread.join
144
      end
145
    end
146 2be0739f Tom McKay
147 1cfcc5dd Tom McKay
    def hammer_context
148
      {
149
        :interactive => false,
150
        :username => 'admin', # TODO: this needs to come from config/settings
151
        :password => 'changeme' # TODO: this needs to come from config/settings
152
      }
153
    end
154
155
    def hammer(context = nil)
156
      HammerCLI::MainCommand.new('', context || hammer_context)
157
    end
158
159 8ac78bfe Tom McKay
    def foreman_organization(options = {})
160 2be0739f Tom McKay
      @organizations ||= {}
161
162
      if options[:name]
163 42d8c0ad Tom McKay
        return nil if options[:name].nil? || options[:name].empty?
164 2be0739f Tom McKay
        options[:id] = @organizations[options[:name]]
165
        if !options[:id]
166 c02629de Tom McKay
          organization = @api.resource(:organizations).call(:index, {
167
                                                              :per_page => 999999,
168
                                                              'search' => "name=\"#{options[:name]}\""
169
                                                            })['results']
170 f370cc85 Tom McKay
          raise _("Organization '%{name}' not found") % {:name => options[:name]} if !organization || organization.empty?
171 42d8c0ad Tom McKay
          options[:id] = organization[0]['id']
172 2be0739f Tom McKay
          @organizations[options[:name]] = options[:id]
173
        end
174
        result = options[:id]
175
      else
176 42d8c0ad Tom McKay
        return nil if options[:id].nil?
177 2be0739f Tom McKay
        options[:name] = @organizations.key(options[:id])
178
        if !options[:name]
179 587327f4 Tom McKay
          organization = @api.resource(:organizations).call(:show, {'id' => options[:id]})
180 f370cc85 Tom McKay
          raise _("Organization 'id=%{id}' not found") % {:id => options[:id]} if !organization || organization.empty?
181 42d8c0ad Tom McKay
          options[:name] = organization['name']
182 2be0739f Tom McKay
          @organizations[options[:name]] = options[:id]
183
        end
184
        result = options[:name]
185
      end
186
187
      result
188
    end
189
190 8ac78bfe Tom McKay
    def foreman_location(options = {})
191 37ef9522 Tom McKay
      @locations ||= {}
192
193
      if options[:name]
194
        return nil if options[:name].nil? || options[:name].empty?
195
        options[:id] = @locations[options[:name]]
196
        if !options[:id]
197 c02629de Tom McKay
          location = @api.resource(:locations).call(:index, {
198
                                                      :per_page => 999999,
199
                                                      'search' => "name=\"#{options[:name]}\""
200
                                                    })['results']
201 f370cc85 Tom McKay
          raise _("Location '%{name}' not found") % {:name => options[:name]} if !location || location.empty?
202 37ef9522 Tom McKay
          options[:id] = location[0]['id']
203
          @locations[options[:name]] = options[:id]
204
        end
205
        result = options[:id]
206
      else
207
        return nil if options[:id].nil?
208
        options[:name] = @locations.key(options[:id])
209
        if !options[:name]
210 587327f4 Tom McKay
          location = @api.resource(:locations).call(:show, {'id' => options[:id]})
211 f370cc85 Tom McKay
          raise _("Location 'id=%{id}' not found") % {:id => options[:id]} if !location || location.empty?
212 37ef9522 Tom McKay
          options[:name] = location['name']
213
          @locations[options[:name]] = options[:id]
214
        end
215
        result = options[:name]
216
      end
217
218
      result
219
    end
220
221 8ac78bfe Tom McKay
    def foreman_role(options = {})
222 bfc065ce Tom McKay
      @roles ||= {}
223
224
      if options[:name]
225
        return nil if options[:name].nil? || options[:name].empty?
226
        options[:id] = @roles[options[:name]]
227
        if !options[:id]
228 c02629de Tom McKay
          role = @api.resource(:roles).call(:index, {
229 26b7d467 Tom McKay
                                              :per_page => 999999,
230 c02629de Tom McKay
                                              'search' => "name=\"#{options[:name]}\""
231
                                            })['results']
232 f370cc85 Tom McKay
          raise _("Role '%{name}' not found") % {:name => options[:name]} if !role || role.empty?
233 bfc065ce Tom McKay
          options[:id] = role[0]['id']
234
          @roles[options[:name]] = options[:id]
235
        end
236
        result = options[:id]
237
      else
238
        return nil if options[:id].nil?
239
        options[:name] = @roles.key(options[:id])
240
        if !options[:name]
241 587327f4 Tom McKay
          role = @api.resource(:roles).call(:show, {'id' => options[:id]})
242 f370cc85 Tom McKay
          raise _("Role 'id=%{id}' not found") % {:id => options[:id]} if !role || role.empty?
243 bfc065ce Tom McKay
          options[:name] = role['name']
244
          @roles[options[:name]] = options[:id]
245
        end
246
        result = options[:name]
247
      end
248
249
      result
250
    end
251
252 8ac78bfe Tom McKay
    def foreman_permission(options = {})
253 37ef9522 Tom McKay
      @permissions ||= {}
254
255
      if options[:name]
256
        return nil if options[:name].nil? || options[:name].empty?
257
        options[:id] = @permissions[options[:name]]
258
        if !options[:id]
259 c02629de Tom McKay
          permission = @api.resource(:permissions).call(:index, {
260
                                                          :per_page => 999999,
261
                                                          'name' => options[:name]
262
                                                        })['results']
263 f370cc85 Tom McKay
          raise _("Permission '%{name}' not found") % {:name => options[:name]} if !permission || permission.empty?
264 37ef9522 Tom McKay
          options[:id] = permission[0]['id']
265
          @permissions[options[:name]] = options[:id]
266
        end
267
        result = options[:id]
268
      else
269
        return nil if options[:id].nil?
270
        options[:name] = @permissions.key(options[:id])
271
        if !options[:name]
272 587327f4 Tom McKay
          permission = @api.resource(:permissions).call(:show, {'id' => options[:id]})
273 f370cc85 Tom McKay
          raise _("Permission 'id=%{id}' not found") % {:id => options[:id]} if !permission || permission.empty?
274 37ef9522 Tom McKay
          options[:name] = permission['name']
275
          @permissions[options[:name]] = options[:id]
276
        end
277
        result = options[:name]
278
      end
279
280
      result
281
    end
282
283 c02629de Tom McKay
    def foreman_filter(role, resource, search)
284
      search = nil if search && search.empty?
285
      filters = @api.resource(:filters).call(:index, {
286
                                               :per_page => 999999,
287
                                               'search' => "role=\"#{role}\""
288
                                             })['results']
289
      filters.each do |filter|
290 c2496839 Tom McKay
        resource_type = (filter['resource_type'] || '').split(':')[-1] # To remove "Katello::" when present
291 90d0b5c8 Tom McKay
        return filter['id'] if resource_type == resource && filter['search'] == search
292 37ef9522 Tom McKay
      end
293
294 c02629de Tom McKay
      nil
295 37ef9522 Tom McKay
    end
296
297 8ac78bfe Tom McKay
    def foreman_environment(options = {})
298 2be0739f Tom McKay
      @environments ||= {}
299
300
      if options[:name]
301 42d8c0ad Tom McKay
        return nil if options[:name].nil? || options[:name].empty?
302 2be0739f Tom McKay
        options[:id] = @environments[options[:name]]
303
        if !options[:id]
304 c02629de Tom McKay
          environment = @api.resource(:environments).call(:index, {
305 26b7d467 Tom McKay
                                                            :per_page => 999999,
306
                                                            'search' => "name=\"#{ options[:name] }\""
307 c02629de Tom McKay
                                                          })['results']
308 f370cc85 Tom McKay
          raise _("Puppet environment '%{name}' not found") % {:name => options[:name]} if !environment || environment.empty?
309 42d8c0ad Tom McKay
          options[:id] = environment[0]['id']
310 2be0739f Tom McKay
          @environments[options[:name]] = options[:id]
311
        end
312
        result = options[:id]
313
      else
314 42d8c0ad Tom McKay
        return nil if options[:id].nil?
315 2be0739f Tom McKay
        options[:name] = @environments.key(options[:id])
316
        if !options[:name]
317 587327f4 Tom McKay
          environment = @api.resource(:environments).call(:show, {'id' => options[:id]})
318 f370cc85 Tom McKay
          raise _("Puppet environment 'id=%{id}' not found") % {:id => options[:id]} if !environment || environment.empty?
319 42d8c0ad Tom McKay
          options[:name] = environment['name']
320 2be0739f Tom McKay
          @environments[options[:name]] = options[:id]
321
        end
322
        result = options[:name]
323
      end
324
325
      result
326
    end
327
328 eb2b87f9 Tom McKay
    def foreman_template_kind(options = {})
329
      @template_kinds ||= {}
330
331
      if options[:name]
332
        return nil if options[:name].nil? || options[:name].empty?
333
        options[:id] = @template_kinds[options[:name]]
334
        if !options[:id]
335
          template_kind = @api.resource(:template_kinds).call(:index, {
336
                                              :per_page => 999999,
337
                                              'search' => "name=\"#{options[:name]}\""
338
                                            })['results']
339 f370cc85 Tom McKay
          raise _("Template kind '%{name}' not found") % {:name => options[:name]} if !template_kind || template_kind.empty?
340 eb2b87f9 Tom McKay
          options[:id] = template_kind[0]['id']
341
          @template_kinds[options[:name]] = options[:id]
342
        end
343
        result = options[:id]
344
      else
345
        return nil if options[:id].nil?
346
        options[:name] = @template_kinds.key(options[:id])
347
        if !options[:name]
348
          template_kind = @api.resource(:template_kinds).call(:show, {'id' => options[:id]})
349 f370cc85 Tom McKay
          raise _("Template kind 'id=%{id}' not found") % {:id => options[:id]} if !template_kind || template_kind.empty?
350 eb2b87f9 Tom McKay
          options[:name] = template_kind['name']
351
          @template_kinds[options[:name]] = options[:id]
352
        end
353
        result = options[:name]
354
      end
355
356
      result
357
    end
358
359 8ac78bfe Tom McKay
    def foreman_operatingsystem(options = {})
360 2be0739f Tom McKay
      @operatingsystems ||= {}
361
362
      if options[:name]
363 42d8c0ad Tom McKay
        return nil if options[:name].nil? || options[:name].empty?
364 2be0739f Tom McKay
        options[:id] = @operatingsystems[options[:name]]
365
        if !options[:id]
366
          (osname, major, minor) = split_os_name(options[:name])
367
          search = "name=\"#{osname}\" and major=\"#{major}\" and minor=\"#{minor}\""
368 c02629de Tom McKay
          operatingsystems = @api.resource(:operatingsystems).call(:index, {
369
                                                                     :per_page => 999999,
370
                                                                     'search' => search
371
                                                                   })['results']
372 1397ae99 Tom McKay
          operatingsystem = operatingsystems[0]
373 f370cc85 Tom McKay
          raise _("Operating system '%{name}' not found") % {:name => options[:name]} if !operatingsystem || operatingsystem.empty?
374 1397ae99 Tom McKay
          options[:id] = operatingsystem['id']
375 2be0739f Tom McKay
          @operatingsystems[options[:name]] = options[:id]
376
        end
377
        result = options[:id]
378
      else
379 42d8c0ad Tom McKay
        return nil if options[:id].nil?
380 2be0739f Tom McKay
        options[:name] = @operatingsystems.key(options[:id])
381
        if !options[:name]
382 587327f4 Tom McKay
          operatingsystem = @api.resource(:operatingsystems).call(:show, {'id' => options[:id]})
383 f370cc85 Tom McKay
          raise _("Operating system 'id=%{id}' not found") % {:id => options[:id]} if !operatingsystem || operatingsystem.empty?
384 cc3fcc43 Tom McKay
          options[:name] = build_os_name(operatingsystem['name'],
385
                                         operatingsystem['major'],
386
                                         operatingsystem['minor'])
387 2be0739f Tom McKay
          @operatingsystems[options[:name]] = options[:id]
388
        end
389
        result = options[:name]
390
      end
391
392
      result
393
    end
394
395 8ac78bfe Tom McKay
    def foreman_architecture(options = {})
396 2be0739f Tom McKay
      @architectures ||= {}
397
398
      if options[:name]
399 42d8c0ad Tom McKay
        return nil if options[:name].nil? || options[:name].empty?
400 2be0739f Tom McKay
        options[:id] = @architectures[options[:name]]
401
        if !options[:id]
402 c02629de Tom McKay
          architecture = @api.resource(:architectures).call(:index, {
403
                                                              :per_page => 999999,
404
                                                              'search' => "name=\"#{options[:name]}\""
405
                                                            })['results']
406 f370cc85 Tom McKay
          raise _("Architecture '%{name}' not found") % {:name => options[:name]} if !architecture || architecture.empty?
407 cc3fcc43 Tom McKay
          options[:id] = architecture[0]['id']
408 2be0739f Tom McKay
          @architectures[options[:name]] = options[:id]
409
        end
410
        result = options[:id]
411
      else
412 42d8c0ad Tom McKay
        return nil if options[:id].nil?
413 2be0739f Tom McKay
        options[:name] = @architectures.key(options[:id])
414
        if !options[:name]
415 587327f4 Tom McKay
          architecture = @api.resource(:architectures).call(:show, {'id' => options[:id]})
416 f370cc85 Tom McKay
          raise _("Architecture 'id=%{id}' not found") % {:id => options[:id]} if !architecture || architecture.empty?
417 cc3fcc43 Tom McKay
          options[:name] = architecture['name']
418 2be0739f Tom McKay
          @architectures[options[:name]] = options[:id]
419
        end
420
        result = options[:name]
421
      end
422
423
      result
424
    end
425
426 8ac78bfe Tom McKay
    def foreman_domain(options = {})
427 2be0739f Tom McKay
      @domains ||= {}
428
429
      if options[:name]
430 42d8c0ad Tom McKay
        return nil if options[:name].nil? || options[:name].empty?
431 2be0739f Tom McKay
        options[:id] = @domains[options[:name]]
432
        if !options[:id]
433 c02629de Tom McKay
          domain = @api.resource(:domains).call(:index, {
434
                                                  :per_page => 999999,
435
                                                  'search' => "name=\"#{options[:name]}\""
436
                                                })['results']
437 f370cc85 Tom McKay
          raise _("Domain '%{name}' not found") % {:name => options[:name]} if !domain || domain.empty?
438 42d8c0ad Tom McKay
          options[:id] = domain[0]['id']
439 2be0739f Tom McKay
          @domains[options[:name]] = options[:id]
440
        end
441
        result = options[:id]
442
      else
443 42d8c0ad Tom McKay
        return nil if options[:id].nil?
444 2be0739f Tom McKay
        options[:name] = @domains.key(options[:id])
445
        if !options[:name]
446 587327f4 Tom McKay
          domain = @api.resource(:domains).call(:show, {'id' => options[:id]})
447 f370cc85 Tom McKay
          raise _("Domain 'id=%{id}' not found") % {:id => options[:id]} if !domain || domain.empty?
448 42d8c0ad Tom McKay
          options[:name] = domain['name']
449 2be0739f Tom McKay
          @domains[options[:name]] = options[:id]
450
        end
451
        result = options[:name]
452
      end
453
454
      result
455
    end
456
457 8ac78bfe Tom McKay
    def foreman_partitiontable(options = {})
458 2be0739f Tom McKay
      @ptables ||= {}
459
460
      if options[:name]
461 42d8c0ad Tom McKay
        return nil if options[:name].nil? || options[:name].empty?
462 2be0739f Tom McKay
        options[:id] = @ptables[options[:name]]
463
        if !options[:id]
464 c02629de Tom McKay
          ptable = @api.resource(:ptables).call(:index, {
465
                                                  :per_page => 999999,
466
                                                  'search' => "name=\"#{options[:name]}\""
467
                                                })['results']
468 f370cc85 Tom McKay
          raise _("Partition table '%{name}' not found") % {:name => options[:name]} if !ptable || ptable.empty?
469 cc3fcc43 Tom McKay
          options[:id] = ptable[0]['id']
470 2be0739f Tom McKay
          @ptables[options[:name]] = options[:id]
471
        end
472
        result = options[:id]
473
      elsif options[:id]
474 42d8c0ad Tom McKay
        return nil if options[:id].nil?
475 2be0739f Tom McKay
        options[:name] = @ptables.key(options[:id])
476
        if !options[:name]
477 587327f4 Tom McKay
          ptable = @api.resource(:ptables).call(:show, {'id' => options[:id]})
478 cc3fcc43 Tom McKay
          options[:name] = ptable['name']
479 2be0739f Tom McKay
          @ptables[options[:name]] = options[:id]
480
        end
481
        result = options[:name]
482
      elsif !options[:name] && !options[:id]
483
        result = ''
484
      end
485
486
      result
487
    end
488
489 1192ff19 Tom McKay
    def foreman_medium(options = {})
490
      @media ||= {}
491
492
      if options[:name]
493
        return nil if options[:name].nil? || options[:name].empty?
494
        options[:id] = @media[options[:name]]
495
        if !options[:id]
496
          ptable = @api.resource(:media).call(:index, {
497
                                                  :per_page => 999999,
498
                                                  'search' => "name=\"#{options[:name]}\""
499
                                                })['results']
500 f370cc85 Tom McKay
          raise _("Partition table '%{name}' not found") % {:name => options[:name]} if !ptable || ptable.empty?
501 1192ff19 Tom McKay
          options[:id] = ptable[0]['id']
502
          @media[options[:name]] = options[:id]
503
        end
504
        result = options[:id]
505
      elsif options[:id]
506
        return nil if options[:id].nil?
507
        options[:name] = @media.key(options[:id])
508
        if !options[:name]
509
          ptable = @api.resource(:media).call(:show, {'id' => options[:id]})
510
          options[:name] = ptable['name']
511
          @media[options[:name]] = options[:id]
512
        end
513
        result = options[:name]
514
      elsif !options[:name] && !options[:id]
515
        result = ''
516
      end
517
518
      result
519
    end
520
521 02387fb5 Tom McKay
    def foreman_host(options = {})
522
      @query_hosts ||= {}
523
524
      if options[:name]
525
        return nil if options[:name].nil? || options[:name].empty?
526
        options[:id] = @query_hosts[options[:name]]
527
        if !options[:id]
528
          host = @api.resource(:hosts).call(:index, {
529
                                              :per_page => 999999,
530
                                              'search' => "name=\"#{options[:name]}\""
531
                                            })['results']
532 f370cc85 Tom McKay
          raise _("Host '%{name}' not found") % {:name => options[:name]} if !host || host.empty?
533 02387fb5 Tom McKay
          options[:id] = host[0]['id']
534
          @query_hosts[options[:name]] = options[:id]
535
        end
536
        result = options[:id]
537
      else
538
        return nil if options[:id].nil?
539
        options[:name] = @query_hosts.key(options[:id])
540
        if !options[:name]
541
          host = @api.resource(:hosts).call(:show, {'id' => options[:id]})
542 f370cc85 Tom McKay
          raise _("Host 'id=%{id}' not found") % {:id => options[:id]} if !host || host.empty?
543 02387fb5 Tom McKay
          options[:name] = host['name']
544
          @query_hosts[options[:name]] = options[:id]
545
        end
546
        result = options[:name]
547
      end
548
549
      result
550
    end
551
552
    def foreman_hostgroup(options = {})
553
      @query_hostgroups ||= {}
554
555
      if options[:name]
556
        return nil if options[:name].nil? || options[:name].empty?
557
        options[:id] = @query_hostgroups[options[:name]]
558
        if !options[:id]
559
          hostgroup = @api.resource(:hostgroups).call(:index, {
560
                                              :per_page => 999999,
561
                                              'search' => "name=\"#{options[:name]}\""
562
                                            })['results']
563 f370cc85 Tom McKay
          raise _("Host Group '%{name}' not found") % {:name => options[:name]} if !hostgroup || hostgroup.empty?
564 02387fb5 Tom McKay
          options[:id] = hostgroup[0]['id']
565
          @query_hostgroups[options[:name]] = options[:id]
566
        end
567
        result = options[:id]
568
      else
569
        return nil if options[:id].nil?
570
        options[:name] = @query_hostgroups.key(options[:id])
571
        if !options[:name]
572
          hostgroup = @api.resource(:hostgroups).call(:show, {'id' => options[:id]})
573 f370cc85 Tom McKay
          raise _("Host Group 'id=%{id}' not found") % {:id => options[:id]} if !hostgroup || hostgroup.empty?
574 02387fb5 Tom McKay
          options[:name] = hostgroup['name']
575
          @query_hostgroups[options[:name]] = options[:id]
576
        end
577
        result = options[:name]
578
      end
579
580
      result
581
    end
582
583 6b4c161c Tom McKay
    def foreman_provisioning_template(options = {})
584
      @query_config_templates ||= {}
585
586
      if options[:name]
587
        return nil if options[:name].nil? || options[:name].empty?
588
        options[:id] = @query_config_templates[options[:name]]
589
        if !options[:id]
590
          config_template = @api.resource(:config_templates).call(:index, {
591
                                              :per_page => 999999,
592
                                              'search' => "name=\"#{options[:name]}\""
593
                                            })['results']
594 f370cc85 Tom McKay
          raise _("Provisioning template '%{name}' not found") % {:name => options[:name]} if !config_template || config_template.empty?
595 6b4c161c Tom McKay
          options[:id] = config_template[0]['id']
596
          @query_config_templates[options[:name]] = options[:id]
597
        end
598
        result = options[:id]
599
      else
600
        return nil if options[:id].nil?
601
        options[:name] = @query_config_templates.key(options[:id])
602
        if !options[:name]
603
          config_template = @api.resource(:config_templates).call(:show, {'id' => options[:id]})
604 f370cc85 Tom McKay
          raise _("Provisioning template 'id=%{id}' not found") % {:id => options[:id]} if !config_template || config_template.empty?
605 6b4c161c Tom McKay
          options[:name] = config_template['name']
606
          @query_config_templates[options[:name]] = options[:id]
607
        end
608
        result = options[:name]
609
      end
610
611
      result
612
    end
613
614 02387fb5 Tom McKay
    def foreman_smart_proxy(options = {})
615
      @query_smart_proxies ||= {}
616
617
      if options[:name]
618
        return nil if options[:name].nil? || options[:name].empty?
619
        options[:id] = @query_smart_proxies[options[:name]]
620
        if !options[:id]
621
          smart_proxy = @api.resource(:smart_proxies).call(:index, {
622
                                              :per_page => 999999,
623
                                              'search' => "name=\"#{options[:name]}\""
624
                                            })['results']
625 f370cc85 Tom McKay
          raise _("Smart Proxy '%{name}' not found") % {:name => options[:name]} if !smart_proxy || smart_proxy.empty?
626 02387fb5 Tom McKay
          options[:id] = smart_proxy[0]['id']
627
          @query_smart_proxies[options[:name]] = options[:id]
628
        end
629
        result = options[:id]
630
      else
631
        return nil if options[:id].nil?
632
        options[:name] = @query_smart_proxies.key(options[:id])
633
        if !options[:name]
634
          smart_proxy = @api.resource(:smart_proxies).call(:show, {'id' => options[:id]})
635 f370cc85 Tom McKay
          raise _("Smart Proxy 'id=%{id}' not found") % {:id => options[:id]} if !smart_proxy || smart_proxy.empty?
636 02387fb5 Tom McKay
          options[:name] = smart_proxy['name']
637
          @query_smart_proxies[options[:name]] = options[:id]
638
        end
639
        result = options[:name]
640
      end
641
642
      result
643
    end
644
645 8c7ba4af Tom McKay
    def lifecycle_environment(organization, options = {})
646
      @lifecycle_environments ||= {}
647
      @lifecycle_environments[organization] ||= {
648 c02629de Tom McKay
      }
649 5880960b Tom McKay
650
      if options[:name]
651
        return nil if options[:name].nil? || options[:name].empty?
652 8c7ba4af Tom McKay
        options[:id] = @lifecycle_environments[organization][options[:name]]
653 5880960b Tom McKay
        if !options[:id]
654 1909f2e6 Tom McKay
          @api.resource(:lifecycle_environments).call(:index, {
655
              :per_page => 999999,
656
              'organization_id' => foreman_organization(:name => organization)
657
          })['results'].each do |environment|
658 8c7ba4af Tom McKay
            @lifecycle_environments[organization][environment['name']] = environment['id']
659 2193a080 Tom McKay
          end
660 8c7ba4af Tom McKay
          options[:id] = @lifecycle_environments[organization][options[:name]]
661 f370cc85 Tom McKay
          raise _("Lifecycle environment '%{name}' not found") % {:name => options[:name]} if !options[:id]
662 5880960b Tom McKay
        end
663
        result = options[:id]
664
      else
665
        return nil if options[:id].nil?
666 8c7ba4af Tom McKay
        options[:name] = @lifecycle_environments.key(options[:id])
667 5880960b Tom McKay
        if !options[:name]
668 bf81b9cf Tom McKay
          environment = @api.resource(:lifecycle_environments).call(:show, {'id' => options[:id]})
669 f370cc85 Tom McKay
          raise _("Lifecycle environment '%{name}' not found") % {:name => options[:name]} if !environment || environment.empty?
670 5880960b Tom McKay
          options[:name] = environment['name']
671 8c7ba4af Tom McKay
          @lifecycle_environments[options[:name]] = options[:id]
672 5880960b Tom McKay
        end
673
        result = options[:name]
674
      end
675
676
      result
677
    end
678
679 8ac78bfe Tom McKay
    def katello_contentview(organization, options = {})
680 612bf01e Tom McKay
      @contentviews ||= {}
681
      @contentviews[organization] ||= {}
682
683
      if options[:name]
684
        return nil if options[:name].nil? || options[:name].empty?
685
        options[:id] = @contentviews[organization][options[:name]]
686
        if !options[:id]
687 8ac78bfe Tom McKay
          @api.resource(:content_views).call(:index, {
688 1909f2e6 Tom McKay
              :per_page => 999999,
689
              'organization_id' => foreman_organization(:name => organization)
690
          })['results'].each do |contentview|
691 c1357ce1 Tom McKay
            @contentviews[organization][contentview['name']] = contentview['id']
692 612bf01e Tom McKay
          end
693
          options[:id] = @contentviews[organization][options[:name]]
694 f370cc85 Tom McKay
          raise _("Content view '%{name}' not found") % {:name => options[:name]} if !options[:id]
695 612bf01e Tom McKay
        end
696
        result = options[:id]
697
      else
698
        return nil if options[:id].nil?
699
        options[:name] = @contentviews.key(options[:id])
700
        if !options[:name]
701 bf81b9cf Tom McKay
          contentview = @api.resource(:content_views).call(:show, {'id' => options[:id]})
702 f370cc85 Tom McKay
          raise _("Puppet contentview 'id=%{id}' not found") % {:id => options[:id]} if !contentview || contentview.empty?
703 612bf01e Tom McKay
          options[:name] = contentview['name']
704
          @contentviews[options[:name]] = options[:id]
705
        end
706
        result = options[:name]
707 0b978f6e Tom McKay
      end
708
709
      result
710
    end
711
712 43345b14 Tom McKay
    def katello_contentviewversion(organization, name, version='latest')
713 1909f2e6 Tom McKay
      @contentviewversions ||= {}
714
      @contentviewversions[organization] ||= {}
715
      versionname = "#{version}|#{name}"
716
717
      return nil if name.nil? || name.empty?
718
      id = @contentviewversions[organization][versionname]
719
      if !id
720
        contentview_id = katello_contentview(organization, :name => name)
721 43345b14 Tom McKay
        contentviewversions = @api.resource(:content_view_versions).call(:index, {
722
                                  :per_page => 999999,
723
                                  'content_view_id' => contentview_id
724
                              })['results'].sort { |a, b| a['created_at'] <=> b['created_at'] }
725
        if version == 'latest'
726
          @contentviewversions[organization][versionname] = contentviewversions[-1]['id']
727
        else
728
          contentviewversions.each do |contentviewversion|
729
            if contentviewversion['version'] == version.to_f
730
              @contentviewversions[organization][versionname] = contentviewversion['id']
731
            end
732 1909f2e6 Tom McKay
          end
733
        end
734
        id = @contentviewversions[organization][versionname]
735 f370cc85 Tom McKay
        raise _("Content view version '%{name}' with version '%{version}' not found") % {:name => name, :version => version} if !id
736 1909f2e6 Tom McKay
      end
737
738
      id
739
    end
740
741 0b978f6e Tom McKay
    def katello_repository(organization, options = {})
742
      @repositories ||= {}
743
      @repositories[organization] ||= {}
744
745
      if options[:name]
746
        return nil if options[:name].nil? || options[:name].empty?
747
        options[:id] = @repositories[organization][options[:name]]
748
        if !options[:id]
749 1909f2e6 Tom McKay
          @api.resource(:repositories).call(:index, {
750
              :per_page => 999999,
751
              'organization_id' => foreman_organization(:name => organization)
752
          })['results'].each do |repository|
753 0b978f6e Tom McKay
            @repositories[organization][repository['name']] = repository['id']
754
          end
755
          options[:id] = @repositories[organization][options[:name]]
756 f370cc85 Tom McKay
          raise _("Repository '%{name}' not found") % {:name => options[:name]} if !options[:id]
757 0b978f6e Tom McKay
        end
758
        result = options[:id]
759
      else
760
        return nil if options[:id].nil?
761
        options[:name] = @repositories.key(options[:id])
762
        if !options[:name]
763
          repository = @api.resource(:repositories).call(:show, {'id' => options[:id]})
764 f370cc85 Tom McKay
          raise _("Puppet repository 'id=%{id}' not found") % {:id => options[:id]} if !repository || repository.empty?
765 0b978f6e Tom McKay
          options[:name] = repository['name']
766
          @repositoriesr[options[:name]] = options[:id]
767
        end
768
        result = options[:name]
769 612bf01e Tom McKay
      end
770
771
      result
772
    end
773
774 a77acc4a Tom McKay
    def katello_hostcollection(organization, options = {})
775
      @hostcollections ||= {}
776
      @hostcollections[organization] ||= {}
777 6bc031bd Tom McKay
778
      if options[:name]
779
        return nil if options[:name].nil? || options[:name].empty?
780 a77acc4a Tom McKay
        options[:id] = @hostcollections[organization][options[:name]]
781 6bc031bd Tom McKay
        if !options[:id]
782 a77acc4a Tom McKay
          @api.resource(:host_collections).call(:index,
783 c02629de Tom McKay
                  {
784
                    :per_page => 999999,
785 a77acc4a Tom McKay
                    'organization_id' => foreman_organization(:name => organization),
786 2645da78 Tom McKay
                    'search' => search_string('host-collections',options[:name])
787 a77acc4a Tom McKay
                  })['results'].each do |hostcollection|
788
            @hostcollections[organization][hostcollection['name']] = hostcollection['id'] if hostcollection
789 6bc031bd Tom McKay
          end
790 a77acc4a Tom McKay
          options[:id] = @hostcollections[organization][options[:name]]
791 f370cc85 Tom McKay
          raise _("Host collection '%{name}' not found") % {:name => options[:name]} if !options[:id]
792 6bc031bd Tom McKay
        end
793
        result = options[:id]
794
      else
795
        return nil if options[:id].nil?
796 a77acc4a Tom McKay
        options[:name] = @hostcollections.key(options[:id])
797 6bc031bd Tom McKay
        if !options[:name]
798 a77acc4a Tom McKay
          hostcollection = @api.resource(:host_collections).call(:show, {'id' => options[:id]})
799 f370cc85 Tom McKay
          raise _("Host collection 'id=%{id}' not found") % {:id => options[:id]} if !hostcollection || hostcollection.empty?
800 a77acc4a Tom McKay
          options[:name] = hostcollection['name']
801
          @hostcollections[options[:name]] = options[:id]
802 6bc031bd Tom McKay
        end
803
        result = options[:name]
804
      end
805
806
      result
807
    end
808
809 43345b14 Tom McKay
    def katello_product(organization, options = {})
810
      @products ||= {}
811
      @products[organization] ||= {}
812
813
      if options[:name]
814
        return nil if options[:name].nil? || options[:name].empty?
815
        options[:id] = @products[organization][options[:name]]
816
        if !options[:id]
817
          @api.resource(:products).call(:index,
818
                  {
819
                    :per_page => 999999,
820
                    'organization_id' => foreman_organization(:name => organization),
821
                    'search' => search_string('host-collections',options[:name])
822
                  })['results'].each do |product|
823
            @products[organization][product['name']] = product['id'] if product
824
          end
825
          options[:id] = @products[organization][options[:name]]
826 f370cc85 Tom McKay
          raise _("Host collection '%{name}' not found") % {:name => options[:name]} if !options[:id]
827 43345b14 Tom McKay
        end
828
        result = options[:id]
829
      else
830
        return nil if options[:id].nil?
831
        options[:name] = @products.key(options[:id])
832
        if !options[:name]
833
          product = @api.resource(:host_collections).call(:show, {'id' => options[:id]})
834 f370cc85 Tom McKay
          raise _("Host collection 'id=%{id}' not found") % {:id => options[:id]} if !product || product.empty?
835 43345b14 Tom McKay
          options[:name] = product['name']
836
          @products[options[:name]] = options[:id]
837
        end
838
        result = options[:name]
839
      end
840
841
      result
842
    end
843
844 c4dbc7a3 Tom McKay
    def foreman_container(options = {})
845
      @containers ||= {}
846
847
      if options[:name]
848
        return nil if options[:name].nil? || options[:name].empty?
849
        options[:id] = @containers[options[:name]]
850
        if !options[:id]
851
          container = @api.resource(:containers).call(:index, {
852
                                                       :per_page => 999999,
853
                                                       'search' => "name=\"#{options[:name]}\""
854
                                                     })['results']
855 f370cc85 Tom McKay
          raise _("Container '%{name}' not found") % {:name => options[:name]} if !container || container.empty?
856 c4dbc7a3 Tom McKay
          options[:id] = container[0]['id']
857
          @containers[options[:name]] = options[:id]
858
        end
859
        result = options[:id]
860
      else
861
        return nil if options[:id].nil?
862
        options[:name] = @containers.key(options[:id])
863
        if !options[:name]
864
          container = @api.resource(:containers).call(:show, {'id' => options[:id]})
865 f370cc85 Tom McKay
          raise _("Container 'id=%{id}' not found") % {:id => options[:id]} if !container || container.empty?
866 c4dbc7a3 Tom McKay
          options[:name] = container['name']
867
          @containers[options[:name]] = options[:id]
868
        end
869
        result = options[:name]
870
      end
871
872
      result
873
    end
874
875
876 2be0739f Tom McKay
    def build_os_name(name, major, minor)
877 8ac78bfe Tom McKay
      name += " #{major}" if major && major != ''
878
      name += ".#{minor}" if minor && minor != ''
879 2be0739f Tom McKay
      name
880
    end
881
882 bfc065ce Tom McKay
    # "Red Hat 6.4" => "Red Hat", "6", "4"
883 8ac78bfe Tom McKay
    # "Red Hat 6"   => "Red Hat", "6", ''
884 2be0739f Tom McKay
    def split_os_name(name)
885 bfc065ce Tom McKay
      tokens = name.split(' ')
886
      is_number = Float(tokens[-1]) rescue false
887
      if is_number
888
        (major, minor) = tokens[-1].split('.').flatten
889
        name = tokens[0...-1].join(' ')
890
      else
891
        name = tokens.join(' ')
892
      end
893 8ac78bfe Tom McKay
      [name, major || '', minor || '']
894 2be0739f Tom McKay
    end
895 317e335f Tom McKay
896 6b4c161c Tom McKay
    def export_column(object, name, field=nil)
897 26b7d467 Tom McKay
      return '' unless object[name]
898 317e335f Tom McKay
      values = CSV.generate do |column|
899
        column << object[name].collect do |fields|
900 6b4c161c Tom McKay
          field.nil? ? yield(fields) : fields[field]
901 317e335f Tom McKay
        end
902
      end
903
      values.delete!("\n")
904
    end
905
906 c02629de Tom McKay
    def collect_column(column)
907
      return [] if column.nil? || column.empty?
908
      CSV.parse_line(column, {:skip_blanks => true}).collect do |value|
909
        yield value
910
      end
911
    end
912
913 317e335f Tom McKay
    def pluralize(name)
914
      case name
915 26b7d467 Tom McKay
      when /smart_proxy/
916
        'smart_proxies'
917
      else
918
        "#{name}s"
919 317e335f Tom McKay
      end
920
    end
921
922
    def associate_organizations(id, organizations, name)
923
      return if organizations.nil?
924
925
      associations ||= {}
926
      CSV.parse_line(organizations).each do |organization|
927
        organization_id = foreman_organization(:name => organization)
928
        if associations[organization].nil?
929
          associations[organization] = @api.resource(:organizations).call(:show, {'id' => organization_id})[pluralize(name)].collect do |reference_object|
930
            reference_object['id']
931
          end
932
        end
933
        associations[organization] += [id] if !associations[organization].include? id
934 1909f2e6 Tom McKay
        @api.resource(:organizations).call(:update, {
935
            'id' => organization_id,
936
            'organization' => {
937
                "#{name}_ids" => associations[organization]
938
            }
939
        })
940 317e335f Tom McKay
      end if organizations && !organizations.empty?
941
    end
942
943
    def associate_locations(id, locations, name)
944
      return if locations.nil?
945
946
      associations ||= {}
947
      CSV.parse_line(locations).each do |location|
948
        location_id = foreman_location(:name => location)
949
        if associations[location].nil?
950
          associations[location] = @api.resource(:locations).call(:show, {'id' => location_id})[pluralize(name)].collect do |reference_object|
951
            reference_object['id']
952
          end
953
        end
954
        associations[location] += [id] if !associations[location].include? id
955
956 1909f2e6 Tom McKay
        @api.resource(:locations).call(:update, {
957
            'id' => location_id,
958
            'location' => {
959
                "#{name}_ids" => associations[location]
960
            }
961
        })
962 317e335f Tom McKay
      end if locations && !locations.empty?
963
    end
964 2645da78 Tom McKay
965 088e0854 Tom McKay
    def apipie_check_param(resource, action, name)
966
      method = @api.resource(pluralize(resource).to_sym).apidoc[:methods].detect do |api_method|
967
        api_method[:name] == action.to_s
968
      end
969
      return false unless method
970
971
      found = method[:params].detect do |param|
972
        param[:full_name] == name
973
      end
974
      if !found
975
        nested =  method[:params].detect do |param|
976
          param[:name] == resource.to_s
977
        end
978
        if nested
979
          found = nested[:params].detect do |param|
980
            param[:full_name] == name
981
          end
982
        end
983
      end
984
      found
985
    end
986
987 02387fb5 Tom McKay
    def count(value)
988
      return 1 if value.nil? || value.empty?
989
      value.to_i
990
    end
991
992 2645da78 Tom McKay
    private
993
994
    def search_string(resource, name)
995
      operator = case resource
996
                 when "gpg-key", "sync-plan", "lifecycle-environment", "host-collections"
997 e9b4881a Tom McKay
                   @server_status['version'] && @server_status['version'].match(/\A1\.6/) ? ':' : '='
998 2645da78 Tom McKay
                 else
999
                   ':'
1000
                 end
1001
      "name#{operator}\"#{name}\""
1002
    end
1003 3c5469d2 Tom McKay
  end
1004
end