Project

General

Profile

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

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

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
# rubocop:disable ClassLength
19
module HammerCLICsv
20
  class BaseCommand < HammerCLI::Apipie::Command
21
    option %w(-v --verbose), :flag, 'be verbose'
22
    option %w(--threads), 'THREAD_COUNT', 'Number of threads to hammer with', :default => 1
23
    option %w(--csv-export), :flag, 'Export current data instead of importing'
24
    option %w(--csv-file), 'FILE_NAME', 'CSV file (default to /dev/stdout with --csv-export, otherwise required)'
25
    option %w(--prefix), 'PREFIX', 'Prefix for all name columns'
26
    option %w(--server), 'SERVER', 'Server URL'
27
    option %w(-u --username), 'USERNAME', 'Username to access server'
28
    option %w(-p --password), 'PASSWORD', 'Password to access server'
29

    
30
    NAME = 'Name'
31
    COUNT = 'Count'
32

    
33
    def execute
34
      if !option_csv_file
35
        if option_csv_export?
36
          # rubocop:disable UselessAssignment
37
          option_csv_file = '/dev/stdout'
38
        else
39
          # rubocop:disable UselessAssignment
40
          option_csv_file = '/dev/stdin'
41
        end
42
      end
43

    
44
      server = option_server ||
45
        HammerCLI::Settings.get(:csv, :host) ||
46
        HammerCLI::Settings.get(:katello, :host) ||
47
        HammerCLI::Settings.get(:foreman, :host)
48
      username = option_username ||
49
        HammerCLI::Settings.get(:csv, :username) ||
50
        HammerCLI::Settings.get(:katello, :username) ||
51
        HammerCLI::Settings.get(:foreman, :username)
52
      password = option_password ||
53
        HammerCLI::Settings.get(:csv, :password) ||
54
        HammerCLI::Settings.get(:katello, :password) ||
55
        HammerCLI::Settings.get(:foreman, :password)
56
      @api = ApipieBindings::API.new({
57
                                       :uri => server,
58
                                       :username => username,
59
                                       :password => password,
60
                                       :api_version => 2
61
                                     })
62

    
63
      @server_status = check_server_status
64

    
65
      option_csv_export? ? export : import
66
      HammerCLI::EX_OK
67
    end
68

    
69
    def check_server_status
70
      server = option_server || HammerCLI::Settings.get(:csv, :host)
71
      username = option_username || HammerCLI::Settings.get(:csv, :username)
72
      password = option_password || HammerCLI::Settings.get(:csv, :password)
73
      url = "#{server}/api/status"
74
      uri = URI(url)
75
      server_status = Net::HTTP.start(uri.host, uri.port,
76
                               :use_ssl => uri.scheme == 'https',
77
                               :verify_mode => OpenSSL::SSL::VERIFY_NONE) do |http|
78
        request = Net::HTTP::Get.new uri.request_uri
79
        request.basic_auth(username, password)
80
        response = http.request(request)
81
        JSON.parse(response.body)
82
      end
83

    
84
      server_status
85
    end
86

    
87
    def namify(name_format, number = 0)
88
      if name_format.index('%')
89
        name = name_format % number
90
      else
91
        name = name_format
92
      end
93
      name = "#{option_prefix}#{name}" if option_prefix
94
      name
95
    end
96

    
97
    def labelize(name)
98
      name.gsub(/[^a-z0-9\-_]/i, '_')
99
    end
100

    
101
    def thread_import(return_headers = false)
102
      csv = []
103
      CSV.foreach(option_csv_file || '/dev/stdin', {
104
                                                     :skip_blanks => true,
105
                                                     :headers => :first_row,
106
                                                     :return_headers => return_headers
107
                                                   }) do |line|
108
        csv << line
109
      end
110
      lines_per_thread = csv.length / option_threads.to_i + 1
111
      splits = []
112

    
113
      option_threads.to_i.times do |current_thread|
114
        start_index = ((current_thread) * lines_per_thread).to_i
115
        finish_index = ((current_thread + 1) * lines_per_thread).to_i
116
        finish_index = csv.length if finish_index > csv.length
117
        if start_index <= finish_index
118
          lines = csv[start_index...finish_index].clone
119
          splits << Thread.new do
120
            lines.each do |line|
121
              if line[NAME][0] != '#'
122
                yield line
123
              end
124
            end
125
          end
126
        end
127
      end
128

    
129
      splits.each do |thread|
130
        thread.join
131
      end
132
    end
133

    
134
    def hammer_context
135
      {
136
        :interactive => false,
137
        :username => 'admin', # TODO: this needs to come from config/settings
138
        :password => 'changeme' # TODO: this needs to come from config/settings
139
      }
140
    end
141

    
142
    def hammer(context = nil)
143
      HammerCLI::MainCommand.new('', context || hammer_context)
144
    end
145

    
146
    def foreman_organization(options = {})
147
      @organizations ||= {}
148

    
149
      if options[:name]
150
        return nil if options[:name].nil? || options[:name].empty?
151
        options[:id] = @organizations[options[:name]]
152
        if !options[:id]
153
          organization = @api.resource(:organizations).call(:index, {
154
                                                              :per_page => 999999,
155
                                                              'search' => "name=\"#{options[:name]}\""
156
                                                            })['results']
157
          raise "Organization '#{options[:name]}' not found" if !organization || organization.empty?
158
          options[:id] = organization[0]['id']
159
          @organizations[options[:name]] = options[:id]
160
        end
161
        result = options[:id]
162
      else
163
        return nil if options[:id].nil?
164
        options[:name] = @organizations.key(options[:id])
165
        if !options[:name]
166
          organization = @api.resource(:organizations).call(:show, {'id' => options[:id]})
167
          raise "Organization 'id=#{options[:id]}' not found" if !organization || organization.empty?
168
          options[:name] = organization['name']
169
          @organizations[options[:name]] = options[:id]
170
        end
171
        result = options[:name]
172
      end
173

    
174
      result
175
    end
176

    
177
    def foreman_location(options = {})
178
      @locations ||= {}
179

    
180
      if options[:name]
181
        return nil if options[:name].nil? || options[:name].empty?
182
        options[:id] = @locations[options[:name]]
183
        if !options[:id]
184
          location = @api.resource(:locations).call(:index, {
185
                                                      :per_page => 999999,
186
                                                      'search' => "name=\"#{options[:name]}\""
187
                                                    })['results']
188
          raise "Location '#{options[:name]}' not found" if !location || location.empty?
189
          options[:id] = location[0]['id']
190
          @locations[options[:name]] = options[:id]
191
        end
192
        result = options[:id]
193
      else
194
        return nil if options[:id].nil?
195
        options[:name] = @locations.key(options[:id])
196
        if !options[:name]
197
          location = @api.resource(:locations).call(:show, {'id' => options[:id]})
198
          raise "Location 'id=#{options[:id]}' not found" if !location || location.empty?
199
          options[:name] = location['name']
200
          @locations[options[:name]] = options[:id]
201
        end
202
        result = options[:name]
203
      end
204

    
205
      result
206
    end
207

    
208
    def foreman_role(options = {})
209
      @roles ||= {}
210

    
211
      if options[:name]
212
        return nil if options[:name].nil? || options[:name].empty?
213
        options[:id] = @roles[options[:name]]
214
        if !options[:id]
215
          role = @api.resource(:roles).call(:index, {
216
                                              :per_page => 999999,
217
                                              'search' => "name=\"#{options[:name]}\""
218
                                            })['results']
219
          raise "Role '#{options[:name]}' not found" if !role || role.empty?
220
          options[:id] = role[0]['id']
221
          @roles[options[:name]] = options[:id]
222
        end
223
        result = options[:id]
224
      else
225
        return nil if options[:id].nil?
226
        options[:name] = @roles.key(options[:id])
227
        if !options[:name]
228
          role = @api.resource(:roles).call(:show, {'id' => options[:id]})
229
          raise "Role 'id=#{options[:id]}' not found" if !role || role.empty?
230
          options[:name] = role['name']
231
          @roles[options[:name]] = options[:id]
232
        end
233
        result = options[:name]
234
      end
235

    
236
      result
237
    end
238

    
239
    def foreman_permission(options = {})
240
      @permissions ||= {}
241

    
242
      if options[:name]
243
        return nil if options[:name].nil? || options[:name].empty?
244
        options[:id] = @permissions[options[:name]]
245
        if !options[:id]
246
          permission = @api.resource(:permissions).call(:index, {
247
                                                          :per_page => 999999,
248
                                                          'name' => options[:name]
249
                                                        })['results']
250
          raise "Permission '#{options[:name]}' not found" if !permission || permission.empty?
251
          options[:id] = permission[0]['id']
252
          @permissions[options[:name]] = options[:id]
253
        end
254
        result = options[:id]
255
      else
256
        return nil if options[:id].nil?
257
        options[:name] = @permissions.key(options[:id])
258
        if !options[:name]
259
          permission = @api.resource(:permissions).call(:show, {'id' => options[:id]})
260
          raise "Permission 'id=#{options[:id]}' not found" if !permission || permission.empty?
261
          options[:name] = permission['name']
262
          @permissions[options[:name]] = options[:id]
263
        end
264
        result = options[:name]
265
      end
266

    
267
      result
268
    end
269

    
270
    def foreman_filter(role, resource, search)
271
      search = nil if search && search.empty?
272
      filters = @api.resource(:filters).call(:index, {
273
                                               :per_page => 999999,
274
                                               'search' => "role=\"#{role}\""
275
                                             })['results']
276
      filters.each do |filter|
277
        resource_type = (filter['resource_type'] || '').split(':')[-1] # To remove "Katello::" when present
278
        return filter['id'] if resource_type == resource && filter['search'] == search
279
      end
280

    
281
      nil
282
    end
283

    
284
    def foreman_environment(options = {})
285
      @environments ||= {}
286

    
287
      if options[:name]
288
        return nil if options[:name].nil? || options[:name].empty?
289
        options[:id] = @environments[options[:name]]
290
        if !options[:id]
291
          environment = @api.resource(:environments).call(:index, {
292
                                                            :per_page => 999999,
293
                                                            'search' => "name=\"#{ options[:name] }\""
294
                                                          })['results']
295
          raise "Puppet environment '#{options[:name]}' not found" if !environment || environment.empty?
296
          options[:id] = environment[0]['id']
297
          @environments[options[:name]] = options[:id]
298
        end
299
        result = options[:id]
300
      else
301
        return nil if options[:id].nil?
302
        options[:name] = @environments.key(options[:id])
303
        if !options[:name]
304
          environment = @api.resource(:environments).call(:show, {'id' => options[:id]})
305
          raise "Puppet environment '#{options[:name]}' not found" if !environment || environment.empty?
306
          options[:name] = environment['name']
307
          @environments[options[:name]] = options[:id]
308
        end
309
        result = options[:name]
310
      end
311

    
312
      result
313
    end
314

    
315
    def foreman_template_kind(options = {})
316
      @template_kinds ||= {}
317

    
318
      if options[:name]
319
        return nil if options[:name].nil? || options[:name].empty?
320
        options[:id] = @template_kinds[options[:name]]
321
        if !options[:id]
322
          template_kind = @api.resource(:template_kinds).call(:index, {
323
                                              :per_page => 999999,
324
                                              'search' => "name=\"#{options[:name]}\""
325
                                            })['results']
326
          raise "Template kind '#{options[:name]}' not found" if !template_kind || template_kind.empty?
327
          options[:id] = template_kind[0]['id']
328
          @template_kinds[options[:name]] = options[:id]
329
        end
330
        result = options[:id]
331
      else
332
        return nil if options[:id].nil?
333
        options[:name] = @template_kinds.key(options[:id])
334
        if !options[:name]
335
          template_kind = @api.resource(:template_kinds).call(:show, {'id' => options[:id]})
336
          raise "Template kind 'id=#{options[:id]}' not found" if !template_kind || template_kind.empty?
337
          options[:name] = template_kind['name']
338
          @template_kinds[options[:name]] = options[:id]
339
        end
340
        result = options[:name]
341
      end
342

    
343
      result
344
    end
345

    
346
    def foreman_operatingsystem(options = {})
347
      @operatingsystems ||= {}
348

    
349
      if options[:name]
350
        return nil if options[:name].nil? || options[:name].empty?
351
        options[:id] = @operatingsystems[options[:name]]
352
        if !options[:id]
353
          (osname, major, minor) = split_os_name(options[:name])
354
          search = "name=\"#{osname}\" and major=\"#{major}\" and minor=\"#{minor}\""
355
          operatingsystems = @api.resource(:operatingsystems).call(:index, {
356
                                                                     :per_page => 999999,
357
                                                                     'search' => search
358
                                                                   })['results']
359
          operatingsystem = operatingsystems[0]
360
          raise "Operating system '#{options[:name]}' not found" if !operatingsystem || operatingsystem.empty?
361
          options[:id] = operatingsystem['id']
362
          @operatingsystems[options[:name]] = options[:id]
363
        end
364
        result = options[:id]
365
      else
366
        return nil if options[:id].nil?
367
        options[:name] = @operatingsystems.key(options[:id])
368
        if !options[:name]
369
          operatingsystem = @api.resource(:operatingsystems).call(:show, {'id' => options[:id]})
370
          raise "Operating system 'id=#{options[:id]}' not found" if !operatingsystem || operatingsystem.empty?
371
          options[:name] = build_os_name(operatingsystem['name'],
372
                                         operatingsystem['major'],
373
                                         operatingsystem['minor'])
374
          @operatingsystems[options[:name]] = options[:id]
375
        end
376
        result = options[:name]
377
      end
378

    
379
      result
380
    end
381

    
382
    def foreman_architecture(options = {})
383
      @architectures ||= {}
384

    
385
      if options[:name]
386
        return nil if options[:name].nil? || options[:name].empty?
387
        options[:id] = @architectures[options[:name]]
388
        if !options[:id]
389
          architecture = @api.resource(:architectures).call(:index, {
390
                                                              :per_page => 999999,
391
                                                              'search' => "name=\"#{options[:name]}\""
392
                                                            })['results']
393
          raise "Architecture '#{options[:name]}' not found" if !architecture || architecture.empty?
394
          options[:id] = architecture[0]['id']
395
          @architectures[options[:name]] = options[:id]
396
        end
397
        result = options[:id]
398
      else
399
        return nil if options[:id].nil?
400
        options[:name] = @architectures.key(options[:id])
401
        if !options[:name]
402
          architecture = @api.resource(:architectures).call(:show, {'id' => options[:id]})
403
          raise "Architecture 'id=#{options[:id]}' not found" if !architecture || architecture.empty?
404
          options[:name] = architecture['name']
405
          @architectures[options[:name]] = options[:id]
406
        end
407
        result = options[:name]
408
      end
409

    
410
      result
411
    end
412

    
413
    def foreman_domain(options = {})
414
      @domains ||= {}
415

    
416
      if options[:name]
417
        return nil if options[:name].nil? || options[:name].empty?
418
        options[:id] = @domains[options[:name]]
419
        if !options[:id]
420
          domain = @api.resource(:domains).call(:index, {
421
                                                  :per_page => 999999,
422
                                                  'search' => "name=\"#{options[:name]}\""
423
                                                })['results']
424
          raise "Domain '#{options[:name]}' not found" if !domain || domain.empty?
425
          options[:id] = domain[0]['id']
426
          @domains[options[:name]] = options[:id]
427
        end
428
        result = options[:id]
429
      else
430
        return nil if options[:id].nil?
431
        options[:name] = @domains.key(options[:id])
432
        if !options[:name]
433
          domain = @api.resource(:domains).call(:show, {'id' => options[:id]})
434
          raise "Domain 'id=#{options[:id]}' not found" if !domain || domain.empty?
435
          options[:name] = domain['name']
436
          @domains[options[:name]] = options[:id]
437
        end
438
        result = options[:name]
439
      end
440

    
441
      result
442
    end
443

    
444
    def foreman_partitiontable(options = {})
445
      @ptables ||= {}
446

    
447
      if options[:name]
448
        return nil if options[:name].nil? || options[:name].empty?
449
        options[:id] = @ptables[options[:name]]
450
        if !options[:id]
451
          ptable = @api.resource(:ptables).call(:index, {
452
                                                  :per_page => 999999,
453
                                                  'search' => "name=\"#{options[:name]}\""
454
                                                })['results']
455
          raise "Partition table '#{options[:name]}' not found" if !ptable || ptable.empty?
456
          options[:id] = ptable[0]['id']
457
          @ptables[options[:name]] = options[:id]
458
        end
459
        result = options[:id]
460
      elsif options[:id]
461
        return nil if options[:id].nil?
462
        options[:name] = @ptables.key(options[:id])
463
        if !options[:name]
464
          ptable = @api.resource(:ptables).call(:show, {'id' => options[:id]})
465
          options[:name] = ptable['name']
466
          @ptables[options[:name]] = options[:id]
467
        end
468
        result = options[:name]
469
      elsif !options[:name] && !options[:id]
470
        result = ''
471
      end
472

    
473
      result
474
    end
475

    
476
    def lifecycle_environment(organization, options = {})
477
      @lifecycle_environments ||= {}
478
      @lifecycle_environments[organization] ||= {
479
      }
480

    
481
      if options[:name]
482
        return nil if options[:name].nil? || options[:name].empty?
483
        options[:id] = @lifecycle_environments[organization][options[:name]]
484
        if !options[:id]
485
          @api.resource(:lifecycle_environments)\
486
            .call(:index, {
487
                    :per_page => 999999,
488
                    'organization_id' => foreman_organization(:name => organization)
489
                  })['results'].each do |environment|
490
            @lifecycle_environments[organization][environment['name']] = environment['id']
491
          end
492
          options[:id] = @lifecycle_environments[organization][options[:name]]
493
          raise "Lifecycle environment '#{options[:name]}' not found" if !options[:id]
494
        end
495
        result = options[:id]
496
      else
497
        return nil if options[:id].nil?
498
        options[:name] = @lifecycle_environments.key(options[:id])
499
        if !options[:name]
500
          environment = @api.resource(:lifecycle_environments).call(:show, {'id' => options[:id]})
501
          raise "Lifecycle environment '#{options[:name]}' not found" if !environment || environment.empty?
502
          options[:name] = environment['name']
503
          @lifecycle_environments[options[:name]] = options[:id]
504
        end
505
        result = options[:name]
506
      end
507

    
508
      result
509
    end
510

    
511
    def katello_contentview(organization, options = {})
512
      @contentviews ||= {}
513
      @contentviews[organization] ||= {}
514

    
515
      if options[:name]
516
        return nil if options[:name].nil? || options[:name].empty?
517
        options[:id] = @contentviews[organization][options[:name]]
518
        if !options[:id]
519
          @api.resource(:content_views).call(:index, {
520
                                               :per_page => 999999,
521
                                               'organization_id' => foreman_organization(:name => organization)
522
                                             })['results'].each do |contentview|
523
            @contentviews[organization][contentview['name']] = contentview['id']
524
          end
525
          options[:id] = @contentviews[organization][options[:name]]
526
          raise "Content view '#{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] = @contentviews.key(options[:id])
532
        if !options[:name]
533
          contentview = @api.resource(:content_views).call(:show, {'id' => options[:id]})
534
          raise "Puppet contentview '#{options[:name]}' not found" if !contentview || contentview.empty?
535
          options[:name] = contentview['name']
536
          @contentviews[options[:name]] = options[:id]
537
        end
538
        result = options[:name]
539
      end
540

    
541
      result
542
    end
543

    
544
    def katello_repository(organization, options = {})
545
      @repositories ||= {}
546
      @repositories[organization] ||= {}
547

    
548
      if options[:name]
549
        return nil if options[:name].nil? || options[:name].empty?
550
        options[:id] = @repositories[organization][options[:name]]
551
        if !options[:id]
552
          @api.resource(:repositories)\
553
            .call(:index, {
554
                    :per_page => 999999,
555
                    'organization_id' => foreman_organization(:name => organization)
556
                  })['results'].each do |repository|
557
            @repositories[organization][repository['name']] = repository['id']
558
          end
559
          options[:id] = @repositories[organization][options[:name]]
560
          raise "Repository '#{options[:name]}' not found" if !options[:id]
561
        end
562
        result = options[:id]
563
      else
564
        return nil if options[:id].nil?
565
        options[:name] = @repositories.key(options[:id])
566
        if !options[:name]
567
          repository = @api.resource(:repositories).call(:show, {'id' => options[:id]})
568
          raise "Puppet repository '#{options[:name]}' not found" if !repository || repository.empty?
569
          options[:name] = repository['name']
570
          @repositoriesr[options[:name]] = options[:id]
571
        end
572
        result = options[:name]
573
      end
574

    
575
      result
576
    end
577

    
578
    def katello_subscription(organization, options = {})
579
      @subscriptions ||= {}
580
      @subscriptions[organization] ||= {}
581

    
582
      if options[:name]
583
        return nil if options[:name].nil? || options[:name].empty?
584
        options[:id] = @subscriptions[organization][options[:name]]
585
        if !options[:id]
586
          results = @api.resource(:subscriptions).call(:index, {
587
                                                         :per_page => 999999,
588
                                                         'organization_id' => foreman_organization(:name => organization),
589
                                                         'search' => "name:\"#{options[:name]}\""
590
                                                       })
591
          raise "No subscriptions match '#{options[:name]}'" if results['subtotal'] == 0
592
          raise "Too many subscriptions match '#{options[:name]}'" if results['subtotal'] > 1
593
          subscription = results['results'][0]
594
          @subscriptions[organization][options[:name]] = subscription['id']
595
          options[:id] = @subscriptions[organization][options[:name]]
596
          raise "Subscription '#{options[:name]}' not found" if !options[:id]
597
        end
598
        result = options[:id]
599
      else
600
        return nil if options[:id].nil?
601
        options[:name] = @subscriptions.key(options[:id])
602
        if !options[:name]
603
          subscription = @api.resource(:subscriptions).call(:show, {'id' => options[:id]})
604
          raise "Subscription '#{options[:name]}' not found" if !subscription || subscription.empty?
605
          options[:name] = subscription['name']
606
          @subscriptions[options[:name]] = options[:id]
607
        end
608
        result = options[:name]
609
      end
610

    
611
      result
612
    end
613

    
614
    def katello_hostcollection(organization, options = {})
615
      @hostcollections ||= {}
616
      @hostcollections[organization] ||= {}
617

    
618
      if options[:name]
619
        return nil if options[:name].nil? || options[:name].empty?
620
        options[:id] = @hostcollections[organization][options[:name]]
621
        if !options[:id]
622
          @api.resource(:host_collections).call(:index,
623
                  {
624
                    :per_page => 999999,
625
                    'organization_id' => foreman_organization(:name => organization),
626
                    'search' => "name:\"#{options[:name]}\""
627
                  })['results'].each do |hostcollection|
628
            @hostcollections[organization][hostcollection['name']] = hostcollection['id'] if hostcollection
629
          end
630
          options[:id] = @hostcollections[organization][options[:name]]
631
          raise "System group '#{options[:name]}' not found" if !options[:id]
632
        end
633
        result = options[:id]
634
      else
635
        return nil if options[:id].nil?
636
        options[:name] = @hostcollections.key(options[:id])
637
        if !options[:name]
638
          hostcollection = @api.resource(:host_collections).call(:show, {'id' => options[:id]})
639
          raise "System group '#{options[:name]}' not found" if !hostcollection || hostcollection.empty?
640
          options[:name] = hostcollection['name']
641
          @hostcollections[options[:name]] = options[:id]
642
        end
643
        result = options[:name]
644
      end
645

    
646
      result
647
    end
648

    
649
    def build_os_name(name, major, minor)
650
      name += " #{major}" if major && major != ''
651
      name += ".#{minor}" if minor && minor != ''
652
      name
653
    end
654

    
655
    # "Red Hat 6.4" => "Red Hat", "6", "4"
656
    # "Red Hat 6"   => "Red Hat", "6", ''
657
    def split_os_name(name)
658
      tokens = name.split(' ')
659
      is_number = Float(tokens[-1]) rescue false
660
      if is_number
661
        (major, minor) = tokens[-1].split('.').flatten
662
        name = tokens[0...-1].join(' ')
663
      else
664
        name = tokens.join(' ')
665
      end
666
      [name, major || '', minor || '']
667
    end
668

    
669
    def export_column(object, name, field)
670
      return '' unless object[name]
671
      values = CSV.generate do |column|
672
        column << object[name].collect do |fields|
673
          fields[field]
674
        end
675
      end
676
      values.delete!("\n")
677
    end
678

    
679
    def collect_column(column)
680
      return [] if column.nil? || column.empty?
681
      CSV.parse_line(column, {:skip_blanks => true}).collect do |value|
682
        yield value
683
      end
684
    end
685

    
686
    def pluralize(name)
687
      case name
688
      when /smart_proxy/
689
        'smart_proxies'
690
      else
691
        "#{name}s"
692
      end
693
    end
694

    
695
    def associate_organizations(id, organizations, name)
696
      return if organizations.nil?
697

    
698
      associations ||= {}
699
      CSV.parse_line(organizations).each do |organization|
700
        organization_id = foreman_organization(:name => organization)
701
        if associations[organization].nil?
702
          associations[organization] = @api.resource(:organizations).call(:show, {'id' => organization_id})[pluralize(name)].collect do |reference_object|
703
            reference_object['id']
704
          end
705
        end
706
        associations[organization] += [id] if !associations[organization].include? id
707
        @api.resource(:organizations)\
708
          .call(:update, {
709
                  'id' => organization_id,
710
                  'organization' => {
711
                    "#{name}_ids" => associations[organization]
712
                  }
713
                })
714
      end if organizations && !organizations.empty?
715
    end
716

    
717
    def associate_locations(id, locations, name)
718
      return if locations.nil?
719

    
720
      associations ||= {}
721
      CSV.parse_line(locations).each do |location|
722
        location_id = foreman_location(:name => location)
723
        if associations[location].nil?
724
          associations[location] = @api.resource(:locations).call(:show, {'id' => location_id})[pluralize(name)].collect do |reference_object|
725
            reference_object['id']
726
          end
727
        end
728
        associations[location] += [id] if !associations[location].include? id
729

    
730
        @api.resource(:locations)\
731
          .call(:update, {
732
                  'id' => location_id,
733
                  'location' => {
734
                    "#{name}_ids" => associations[location]
735
                  }
736
                })
737
      end if locations && !locations.empty?
738
    end
739
  end
740
end