Project

General

Profile

Revision 9d9e4494

Added by Thomas McKay almost 9 years ago

cv - provider, products, repo creation

View differences:

hammer-it
10 10
bundle exec hammer -v csv:hosts              --verbose --csv-file test/data/hosts.csv
11 11
bundle exec hammer -v csv:puppetfacts        --verbose --csv-file test/data/puppetfacts.csv
12 12

  
13
bundle exec hammer -v csv:products           --verbose --csv-file test/data/products.csv
14

  
13 15
bundle exec hammer -v csv:systemgroups       --verbose --csv-file test/data/systemgroups.csv
14 16
bundle exec hammer -v csv:systems            --verbose --csv-file test/data/systems.csv
lib/hammer_cli_csv.rb
24 24
  require 'hammer_cli_csv/users'
25 25
  require 'hammer_cli_csv/puppet_facts'
26 26

  
27
  require 'hammer_cli_csv/content_views'
28
  require 'hammer_cli_csv/subscriptions'
27 29
  require 'hammer_cli_csv/systems'
28 30
  require 'hammer_cli_csv/system_groups'
31
  require 'hammer_cli_csv/products'
29 32
end
lib/hammer_cli_csv/base.rb
35 35
    NAME = 'Name'
36 36
    COUNT = 'Count'
37 37

  
38
    HEADERS = {'Accept' => 'version=2,application/json'}
39

  
40 38
    option ["-v", "--verbose"], :flag, "be verbose"
41 39
    option ['--threads'], 'THREAD_COUNT', 'Number of threads to hammer with', :default => 1
42 40
    option ['--csv-export'], :flag, 'Export current data instead of importing'
......
61 59
      @k_systemgroup_api ||= KatelloApi::Resources::SystemGroup.new(@init_options.merge({:base_url => "#{@init_options[:base_url]}"}))
62 60
      @k_environment_api ||= KatelloApi::Resources::Environment.new(@init_options.merge({:base_url => "#{@init_options[:base_url]}"}))
63 61
      @k_contentview_api ||= KatelloApi::Resources::ContentView.new(@init_options.merge({:base_url => "#{@init_options[:base_url]}"}))
62
      @k_provider_api ||= KatelloApi::Resources::Provider.new(@init_options.merge({:base_url => "#{@init_options[:base_url]}"}))
63
      @k_product_api ||= KatelloApi::Resources::Product.new(@init_options.merge({:base_url => "#{@init_options[:base_url]}"}))
64
      @k_repository_api ||= KatelloApi::Resources::Repository.new(@init_options.merge({:base_url => "#{@init_options[:base_url]}"}))
65
      @k_contentviewdefinition_api ||= KatelloApi::Resources::ContentViewDefinition.new(@init_options.merge({:base_url => "#{@init_options[:base_url]}"}))
66
      @k_subscription_api ||= KatelloApi::Resources::Subscription.new(@init_options.merge({:base_url => "#{@init_options[:base_url]}"}))
64 67

  
65 68
      @f_architecture_api ||= ForemanApi::Resources::Architecture.new(@init_options)
66 69
      @f_domain_api ||= ForemanApi::Resources::Domain.new(@init_options)
......
91 94
      end
92 95
    end
93 96

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

  
94 101
    def thread_import(return_headers=false)
95 102
      csv = []
96 103
      CSV.foreach(csv_file, {:skip_blanks => true, :headers => :first_row, :return_headers => return_headers}) do |line|
......
124 131
        return nil if options[:name].nil? || options[:name].empty?
125 132
        options[:id] = @organizations[options[:name]]
126 133
        if !options[:id]
127
          organization = @f_organization_api.index({'search' => "name=\"#{options[:name]}\""}, HEADERS)[0]['results']
134
          organization = @f_organization_api.index({'search' => "name=\"#{options[:name]}\""})[0]['results']
128 135
          raise RuntimeError.new("Organization '#{options[:name]}' not found") if !organization || organization.empty?
129 136
          options[:id] = organization[0]['id']
130 137
          @organizations[options[:name]] = options[:id]
......
134 141
        return nil if options[:id].nil?
135 142
        options[:name] = @organizations.key(options[:id])
136 143
        if !options[:name]
137
          organization = @f_organization_api.show({'id' => options[:id]}, HEADERS)[0]
144
          organization = @f_organization_api.show({'id' => options[:id]})[0]
138 145
          raise RuntimeError.new("Organization 'id=#{options[:id]}' not found") if !organization || organization.empty?
139 146
          options[:name] = organization['name']
140 147
          @organizations[options[:name]] = options[:id]
......
152 159
        return nil if options[:name].nil? || options[:name].empty?
153 160
        options[:id] = @environments[options[:name]]
154 161
        if !options[:id]
155
          environment = @f_environment_api.index({'search' => "name=\"#{options[:name]}\""}, HEADERS)[0]['results']
162
          environment = @f_environment_api.index({'search' => "name=\"#{options[:name]}\""})[0]['results']
156 163
          raise RuntimeError.new("Puppet environment '#{options[:name]}' not found") if !environment || environment.empty?
157 164
          options[:id] = environment[0]['id']
158 165
          @environments[options[:name]] = options[:id]
......
162 169
        return nil if options[:id].nil?
163 170
        options[:name] = @environments.key(options[:id])
164 171
        if !options[:name]
165
          environment = @f_environment_api.show({'id' => options[:id]}, HEADERS)[0]
172
          environment = @f_environment_api.show({'id' => options[:id]})[0]
166 173
          raise RuntimeError.new("Puppet environment '#{options[:name]}' not found") if !environment || environment.empty?
167 174
          options[:name] = environment['name']
168 175
          @environments[options[:name]] = options[:id]
......
182 189
        if !options[:id]
183 190
          (osname, major, minor) = split_os_name(options[:name])
184 191
          search = "name=\"#{osname}\" and major=\"#{major}\" and minor=\"#{minor}\""
185
          operatingsystems = @f_operatingsystem_api.index({'search' => search}, HEADERS)[0]['results']
192
          operatingsystems = @f_operatingsystem_api.index({'search' => search})[0]['results']
186 193
          operatingsystem = operatingsystems[0]
187 194
          raise RuntimeError.new("Operating system '#{options[:name]}' not found") if !operatingsystem || operatingsystem.empty?
188 195
          options[:id] = operatingsystem['id']
......
193 200
        return nil if options[:id].nil?
194 201
        options[:name] = @operatingsystems.key(options[:id])
195 202
        if !options[:name]
196
          operatingsystem = @f_operatingsystem_api.show({'id' => options[:id]}, HEADERS)[0]
203
          operatingsystem = @f_operatingsystem_api.show({'id' => options[:id]})[0]
197 204
          raise RuntimeError.new("Operating system 'id=#{options[:id]}' not found") if !operatingsystem || operatingsystem.empty?
198 205
          options[:name] = build_os_name(operatingsystem['name'],
199 206
                                         operatingsystem['major'],
......
213 220
        return nil if options[:name].nil? || options[:name].empty?
214 221
        options[:id] = @architectures[options[:name]]
215 222
        if !options[:id]
216
          architecture = @f_architecture_api.index({'search' => "name=\"#{options[:name]}\""}, HEADERS)[0]['results']
223
          architecture = @f_architecture_api.index({'search' => "name=\"#{options[:name]}\""})[0]['results']
217 224
          raise RuntimeError.new("Architecture '#{options[:name]}' not found") if !architecture || architecture.empty?
218 225
          options[:id] = architecture[0]['id']
219 226
          @architectures[options[:name]] = options[:id]
......
223 230
        return nil if options[:id].nil?
224 231
        options[:name] = @architectures.key(options[:id])
225 232
        if !options[:name]
226
          architecture = @f_architecture_api.show({'id' => options[:id]}, HEADERS)[0]
233
          architecture = @f_architecture_api.show({'id' => options[:id]})[0]
227 234
          raise RuntimeError.new("Architecture 'id=#{options[:id]}' not found") if !architecture || architecture.empty?
228 235
          options[:name] = architecture['name']
229 236
          @architectures[options[:name]] = options[:id]
......
241 248
        return nil if options[:name].nil? || options[:name].empty?
242 249
        options[:id] = @domains[options[:name]]
243 250
        if !options[:id]
244
          domain = @f_domain_api.index({'search' => "name=\"#{options[:name]}\""}, HEADERS)[0]['results']
251
          domain = @f_domain_api.index({'search' => "name=\"#{options[:name]}\""})[0]['results']
245 252
          raise RuntimeError.new("Domain '#{options[:name]}' not found") if !domain || domain.empty?
246 253
          options[:id] = domain[0]['id']
247 254
          @domains[options[:name]] = options[:id]
......
251 258
        return nil if options[:id].nil?
252 259
        options[:name] = @domains.key(options[:id])
253 260
        if !options[:name]
254
          domain = @f_domain_api.show({'id' => options[:id]}, HEADERS)[0]
261
          domain = @f_domain_api.show({'id' => options[:id]})[0]
255 262
          raise RuntimeError.new("Domain 'id=#{options[:id]}' not found") if !domain || domain.empty?
256 263
          options[:name] = domain['name']
257 264
          @domains[options[:name]] = options[:id]
......
269 276
        return nil if options[:name].nil? || options[:name].empty?
270 277
        options[:id] = @ptables[options[:name]]
271 278
        if !options[:id]
272
          ptable = @f_partitiontable_api.index({'search' => "name=\"#{options[:name]}\""}, HEADERS)[0]['results']
279
          ptable = @f_partitiontable_api.index({'search' => "name=\"#{options[:name]}\""})[0]['results']
273 280
          raise RuntimeError.new("Partition table '#{options[:name]}' not found") if !ptable || ptable.empty?
274 281
          options[:id] = ptable[0]['id']
275 282
          @ptables[options[:name]] = options[:id]
......
279 286
        return nil if options[:id].nil?
280 287
        options[:name] = @ptables.key(options[:id])
281 288
        if !options[:name]
282
          ptable = @f_partitiontable_api.show({'id' => options[:id]}, HEADERS)[0]
289
          ptable = @f_partitiontable_api.show({'id' => options[:id]})[0]
283 290
          options[:name] = ptable['name']
284 291
          @ptables[options[:name]] = options[:id]
285 292
        end
......
299 306
        return nil if options[:name].nil? || options[:name].empty?
300 307
        options[:id] = @environments[organization][options[:name]]
301 308
        if !options[:id]
302
          @k_environment_api.index({'organization_id' => organization}, HEADERS)[0].each do |environment|
309
          @k_environment_api.index({'organization_id' => organization})[0].each do |environment|
303 310
            @environments[organization][environment['environment']['name']] = environment['environment']['id']
304 311
          end
305 312
          options[:id] = @environments[organization][options[:name]]
......
310 317
        return nil if options[:id].nil?
311 318
        options[:name] = @environments.key(options[:id])
312 319
        if !options[:name]
313
          environment = @k_environment_api.show({'id' => options[:id]}, HEADERS)[0]
320
          environment = @k_environment_api.show({'id' => options[:id]})[0]
314 321
          raise RuntimeError.new("Puppet environment '#{options[:name]}' not found") if !environment || environment.empty?
315 322
          options[:name] = environment['name']
316 323
          @environments[options[:name]] = options[:id]
......
329 336
        return nil if options[:name].nil? || options[:name].empty?
330 337
        options[:id] = @contentviews[organization][options[:name]]
331 338
        if !options[:id]
332
          puts @k_contentview_api.index({'organization_id' => organization, 'environment_id' => 2, 'label' => 'Default_Organization_View'}, HEADERS)[0]
333
          @k_contentview_api.index({'organization_id' => organization, 'label' => options[:name]}, HEADERS)[0].each do |contentview|
339
          puts "CONTENTVIEWS=#{@k_contentview_api.index({'organization_id' => organization, 'environment_id' => 2, 'label' => 'Default_Organization_View'})[0]}"
340
          @k_contentview_api.index({
341
                                     'organization_id' => organization,
342
                                     'label' => options[:name]
343
                                   })[0].each do |contentview|
334 344
            puts contentview
335 345
            @contentviews[organization][contentview['contentview']['name']] = contentview['contentview']['id']
336 346
          end
......
342 352
        return nil if options[:id].nil?
343 353
        options[:name] = @contentviews.key(options[:id])
344 354
        if !options[:name]
345
          contentview = @k_contentview_api.show({'id' => options[:id]}, HEADERS)[0]
355
          contentview = @k_contentview_api.show({'id' => options[:id]})[0]
346 356
          raise RuntimeError.new("Puppet contentview '#{options[:name]}' not found") if !contentview || contentview.empty?
347 357
          options[:name] = contentview['name']
348 358
          @contentviews[options[:name]] = options[:id]
......
353 363
      result
354 364
    end
355 365

  
366
    def katello_subscription(organization, options={})
367
      @subscriptions ||= {}
368
      @subscriptions[organization] ||= {}
369

  
370
      if options[:name]
371
        return nil if options[:name].nil? || options[:name].empty?
372
        options[:id] = @subscriptions[organization][options[:name]]
373
        if !options[:id]
374
          puts @k_subscription_api.index({
375
                                           'organization_id' => organization,
376
                                           'search' => "product_id:#{options[:name]}"
377
                                         })[0]
378
          @k_subscription_api.index({
379
                                      'organization_id' => organization,
380
                                      'search' => "'product_id:#{name}'"
381
                                    })[0]['results'][0].each do |subscription|
382
            puts subscription
383
            @subscriptions[organization][subscription['subscription']['name']] = subscription['subscription']['id']
384
          end
385
          options[:id] = @subscriptions[organization][options[:name]]
386
          raise RuntimeError.new("Puppet subscription '#{options[:name]}' not found") if !options[:id]
387
        end
388
        result = options[:id]
389
      else
390
        return nil if options[:id].nil?
391
        options[:name] = @subscriptions.key(options[:id])
392
        if !options[:name]
393
          subscription = @k_subscription_api.show({'id' => options[:id]})[0]
394
          raise RuntimeError.new("Puppet subscription '#{options[:name]}' not found") if !subscription || subscription.empty?
395
          options[:name] = subscription['name']
396
          @subscriptions[options[:name]] = options[:id]
397
        end
398
        result = options[:name]
399
      end
400

  
401
      result
402
    end
403

  
356 404
    def build_os_name(name, major, minor)
357 405
      name += " #{major}" if major && major != ""
358 406
      name += ".#{minor}" if minor && minor != ""
lib/hammer_cli_csv/content_views.rb
1
# Copyright (c) 2013 Red Hat
2
#
3
# MIT License
4
#
5
# Permission is hereby granted, free of charge, to any person obtaining
6
# a copy of this software and associated documentation files (the
7
# "Software"), to deal in the Software without restriction, including
8
# without limitation the rights to use, copy, modify, merge, publish,
9
# distribute, sublicense, and/or sell copies of the Software, and to
10
# permit persons to whom the Software is furnished to do so, subject to
11
# the following conditions:
12
#
13
# The above copyright notice and this permission notice shall be
14
# included in all copies or substantial portions of the Software.
15
#
16
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
#
24
#
25
# -= Systems CSV =-
26
#
27
# Columns
28
#   Name
29
#     - System name
30
#     - May contain '%d' which will be replaced with current iteration number of Count
31
#     - eg. "os%d" -> "os1"
32
#   Count
33
#     - Number of times to iterate on this line of the CSV file
34

  
35

  
36
require 'hammer_cli'
37
require 'katello_api'
38
require 'foreman_api'
39
require 'json'
40
require 'csv'
41
require 'uri'
42

  
43
module HammerCLICsv
44
  class ContentViewsCommand < BaseCommand
45

  
46
    ORGANIZATION = 'Organization'
47
    DESCRIPTION = 'Description'
48
    PRODUCT = 'Product'
49
    REPOSITORY = 'Repository'
50

  
51
    def export
52
      # TODO
53
    end
54

  
55
    def import
56
      @existing_contentviews = {}
57

  
58
      thread_import do |line|
59
        create_contentviews_from_csv(line)
60
      end
61
    end
62

  
63
    def create_contentviews_from_csv(line)
64
      if !@existing_contentviews[line[ORGANIZATION]]
65
        @existing_contentviews[line[ORGANIZATION]] ||= {}
66
        @k_contentviewdefinition_api.index({'organization_id' => line[ORGANIZATION], 'page_size' => 999999, 'paged' => true})[0]['results'].each do |contentview|
67
          @existing_contentviews[line[ORGANIZATION]][contentview['name']] = contentview['id'] if contentview
68
        end
69
      end
70

  
71
      line[COUNT].to_i.times do |number|
72
        name = namify(line[NAME], number)
73
        contentview_id = @existing_contentviews[line[ORGANIZATION]][name]
74
        if !contentview_id
75
          print "Creating content view '#{name}'..." if verbose?
76
          contentview_id = @k_contentviewdefinition_api.create({
77
                                                                 'organization_id' => line[ORGANIZATION],
78
                                                                 'name' => name,
79
                                                                 'label' => labelize(name),
80
                                                                 'description' => line[DESCRIPTION],
81
                                                                 'composite' => false # TODO: add column?
82
                                                               })[0]['id']
83
          @existing_contentviews[line[ORGANIZATION]][name] = contentview_id
84
        else
85
          print "Updating content view '#{name}'..." if verbose?
86
          @k_contentviewdefinition_api.create({
87
                                                'description' => line[DESCRIPTION],
88
                                              })
89
        end
90

  
91
        if line[REPOSITORY]
92
          puts "UPDATING REPOSITORY"
93
        elsif line[PRODUCT]
94
          puts "UPDATING PRODUCT"
95
        end
96
        print "done\n" if verbose?
97

  
98
=begin
99
        # Only creating repositories, not updating
100
        repository_name = namify(line[REPOSITORY], number)
101
        if !@existing_repositories[line[ORGANIZATION] + name][labelize(repository_name)]
102
          print "Creating repository '#{repository_name}' in contentview '#{name}'..." if verbose?
103
          @k_repository_api.create({
104
                                     'name' => repository_name,
105
                                     'label' => labelize(repository_name),
106
                                     'contentview_id' => contentview_id,
107
                                     'url' => line[REPOSITORY_URL],
108
                                     'content_type' => line[REPOSITORY_TYPE]
109
                                   })
110
          print "done\n" if verbose?
111
        end
112
=end
113
      end
114

  
115
    rescue RuntimeError => e
116
      raise RuntimeError.new("#{e}\n       #{line}")
117
    end
118
  end
119

  
120
  HammerCLI::MainCommand.subcommand("csv:contentviews", "import/export content views", HammerCLICsv::ContentViewsCommand)
121
end
lib/hammer_cli_csv/products.rb
1
# Copyright (c) 2013 Red Hat
2
#
3
# MIT License
4
#
5
# Permission is hereby granted, free of charge, to any person obtaining
6
# a copy of this software and associated documentation files (the
7
# "Software"), to deal in the Software without restriction, including
8
# without limitation the rights to use, copy, modify, merge, publish,
9
# distribute, sublicense, and/or sell copies of the Software, and to
10
# permit persons to whom the Software is furnished to do so, subject to
11
# the following conditions:
12
#
13
# The above copyright notice and this permission notice shall be
14
# included in all copies or substantial portions of the Software.
15
#
16
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
#
24
#
25
# -= Systems CSV =-
26
#
27
# Columns
28
#   Name
29
#     - System name
30
#     - May contain '%d' which will be replaced with current iteration number of Count
31
#     - eg. "os%d" -> "os1"
32
#   Count
33
#     - Number of times to iterate on this line of the CSV file
34

  
35

  
36
require 'hammer_cli'
37
require 'katello_api'
38
require 'foreman_api'
39
require 'json'
40
require 'csv'
41
require 'uri'
42

  
43
module HammerCLICsv
44
  class ProductsCommand < BaseCommand
45

  
46
    ORGANIZATION = 'Organization'
47
    PROVIDER = 'Provider'
48
    REPOSITORY = 'Repository'
49
    REPOSITORY_TYPE = 'Repository Type'
50
    REPOSITORY_URL = 'Repository Url'
51

  
52
    def export
53
      # TODO
54
    end
55

  
56
    def import
57
      @existing_products = {}
58
      @existing_providers = {}
59
      @existing_repositories = {}
60

  
61
      thread_import do |line|
62
        create_products_from_csv(line)
63
      end
64
    end
65

  
66
    def create_products_from_csv(line)
67
      if !@existing_providers[line[ORGANIZATION]]
68

  
69
        @k_provider_api.index({'organization_id' => line[ORGANIZATION], 'page_size' => 999999, 'paged' => true})[0]['results'].each do |provider|
70
          @existing_providers[line[ORGANIZATION]] ||= {}
71
          @existing_providers[line[ORGANIZATION]][provider['name']] = provider['id'] if provider
72
        end
73

  
74
        @k_product_api.index({'organization_id' => line[ORGANIZATION], 'page_size' => 999999, 'paged' => true})[0]['results'].each do |product|
75
          @existing_products[line[ORGANIZATION]] ||= {}
76
          @existing_products[line[ORGANIZATION]][product['name']] = product['id'] if product
77

  
78
          if product
79
            @k_repository_api.index({
80
                                      'organization_id' => line[ORGANIZATION],
81
                                      'product_id' => product['id'],
82
                                      'enabled' => true,
83
                                      'library' => true,
84
                                      'page_size' => 999999, 'paged' => true
85
                                    })[0]['results'].each do |repository|
86
              @existing_repositories[line[ORGANIZATION]+product['name']] ||= {}
87
              @existing_repositories[line[ORGANIZATION]+product['name']][repository['label']] = repository['id']
88
            end
89
          end
90
        end
91
      end
92

  
93
      # Only creating providers, not updating
94
      if !@existing_providers[line[ORGANIZATION]][line[PROVIDER]]
95
        print "Creating provider '#{line[PROVIDER]}'..." if verbose?
96
        id = @k_provider_api.create({
97
                                      'name' => line[PROVIDER],
98
                                      'organization_id' => line[ORGANIZATION]
99
                                    })[0]['id']
100
        @existing_providers[line[ORGANIZATION]][line[PROVIDER]] = id
101
        print "done\n" if verbose?
102
      end
103
      provider_id = @existing_providers[line[ORGANIZATION]][line[PROVIDER]]
104

  
105
      # Only creating products, not updating
106
      line[COUNT].to_i.times do |number|
107
        name = namify(line[NAME], number)
108
        product_id = @existing_products[line[ORGANIZATION]][name]
109
        if !product_id
110
          print "Creating product '#{name}'..." if verbose?
111
          product_id = @k_product_api.create({
112
                                               'name' => name,
113
                                               'provider_id' => provider_id
114
                                             })[0]['id']
115
          @existing_products[line[ORGANIZATION]][name] = product_id
116
          print "done\n" if verbose?
117
        end
118
        @existing_repositories[line[ORGANIZATION] + name] ||= {}
119

  
120
        # Only creating repositories, not updating
121
        repository_name = namify(line[REPOSITORY], number)
122
        if !@existing_repositories[line[ORGANIZATION] + name][labelize(repository_name)]
123
          print "Creating repository '#{repository_name}' in product '#{name}'..." if verbose?
124
          @k_repository_api.create({
125
                                     'name' => repository_name,
126
                                     'label' => labelize(repository_name),
127
                                     'product_id' => product_id,
128
                                     'url' => line[REPOSITORY_URL],
129
                                     'content_type' => line[REPOSITORY_TYPE]
130
                                   })
131
          print "done\n" if verbose?
132
        end
133
      end
134

  
135
    rescue RuntimeError => e
136
      raise RuntimeError.new("#{e}\n       #{line}")
137
    end
138
  end
139

  
140
  HammerCLI::MainCommand.subcommand("csv:products", "import/export products and repositories", HammerCLICsv::ProductsCommand)
141
end
lib/hammer_cli_csv/subscriptions.rb
1
# Copyright (c) 2013 Red Hat
2
#
3
# MIT License
4
#
5
# Permission is hereby granted, free of charge, to any person obtaining
6
# a copy of this software and associated documentation files (the
7
# "Software"), to deal in the Software without restriction, including
8
# without limitation the rights to use, copy, modify, merge, publish,
9
# distribute, sublicense, and/or sell copies of the Software, and to
10
# permit persons to whom the Software is furnished to do so, subject to
11
# the following conditions:
12
#
13
# The above copyright notice and this permission notice shall be
14
# included in all copies or substantial portions of the Software.
15
#
16
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
#
24
#
25
# -= Systems CSV =-
26
#
27
# Columns
28
#   Name
29
#     - System name
30
#     - May contain '%d' which will be replaced with current iteration number of Count
31
#     - eg. "os%d" -> "os1"
32
#   Count
33
#     - Number of times to iterate on this line of the CSV file
34

  
35

  
36
require 'hammer_cli'
37
require 'katello_api'
38
require 'foreman_api'
39
require 'json'
40
require 'csv'
41
require 'uri'
42

  
43
module HammerCLICsv
44
  class SubscriptionsCommand < BaseCommand
45

  
46
    ORGANIZATION = 'Organization'
47
    MANIFEST = 'Manifest File'
48

  
49
    def export
50
      # TODO
51
    end
52

  
53
    def import
54
      thread_import do |line|
55
        create_subscriptions_from_csv(line)
56
      end
57
    end
58

  
59
    def create_subscriptions_from_csv(line)
60
      puts "TODO: import #{line[MANIFEST]} into organization #{line[ORGANIZATION]}"
61
    rescue RuntimeError => e
62
      raise RuntimeError.new("#{e}\n       #{line}")
63
    end
64
  end
65

  
66
  HammerCLI::MainCommand.subcommand("csv:subscriptions", "import subscriptions", HammerCLICsv::SubscriptionsCommand)
67
end
lib/hammer_cli_csv/systems.rb
69 69
    def import
70 70
      @existing = {}
71 71

  
72
      #puts "ENVIRONMENT #{katello_environment('ACME_Corporation', :name => 'Library')}"
73
      #puts "CONTENTVIEW #{katello_contentview('ACME_Corporation', :name => 'Default_Organization_View')}"
74

  
75 72
      thread_import do |line|
76 73
        create_systems_from_csv(line)
77 74
      end
78 75
    end
79 76

  
80 77
    def create_systems_from_csv(line)
81

  
82
      @k_system_api.index({'organization_id' => line[ORGANIZATION], 'page_size' => 999999, 'paged' => true}, HEADERS)[0]['results'].each do |system|
83
        @existing[line[ORGANIZATION]] ||= {}
84
        @existing[line[ORGANIZATION]][system['name']] = system['id'] if system
85
      end
86

  
87
      facts = {}
88
      facts['cpu.core(s)_per_socket'] = line[CORES]
89
      facts['cpu.cpu_socket(s)'] = line[SOCKETS]
90
      facts['memory.memtotal'] = line[RAM]
91
      facts['uname.machine'] = line[ARCHITECTURE]
92
      if line[OPERATINGSYSTEM].index(' ')
93
        (facts['distribution.name'], facts['distribution.version']) = line[OPERATINGSYSTEM].split(' ')
94
      else
95
        (facts['distribution.name'], facts['distribution.version']) = ['RHEL', line[OPERATINGSYSTEM]]
78
      if !@existing[line[ORGANIZATION]]
79
        @existing[line[ORGANIZATION]] = {}
80
        @k_system_api.index({'organization_id' => line[ORGANIZATION], 'page_size' => 999999, 'paged' => true})[0]['results'].each do |system|
81
          @existing[line[ORGANIZATION]][system['name']] = system['uuid'] if system
82
        end
96 83
      end
97 84

  
98 85
      line[COUNT].to_i.times do |number|
99 86
        name = namify(line[NAME], number)
100
        if !@existing.include? name
87

  
88
        subscriptions(line).each do |subscription|
89
          puts subscription
90
          katello_subscription(line[ORGANIZATION], :name => subscription[:number])
91
        end
92

  
93
        if !@existing[line[ORGANIZATION]].include? name
101 94
          print "Creating system '#{name}'..." if verbose?
102 95
          @k_system_api.create({
103 96
                                 'name' => name,
104
                                 'organization_id' => 'ACME_Corporation', #foreman_organization(:name => line[ORGANIZATION]),
105
                                 'environment_id' => 1, #katello_environment(:name => line[ENVIRONMENT]),
106
                                 'content_view_id' => 1, #katello_contentview(:name => line[CONTENTVIEW]),
107
                                 'facts' => facts,
108
                                 'cp_type' => 'system'
109
                           }, HEADERS)
110
          print "done\n" if verbose?
97
                                 'organization_id' => line[ORGANIZATION],
98
                                 'environment_id' => katello_environment(line[ORGANIZATION], :name => line[ENVIRONMENT]),
99
                                 'content_view_id' => 2, # TODO: katello_contentview(line[ORGANIZATION], :name => line[CONTENTVIEW]),
100
                                 'facts' => facts(line),
101
                                 'installedProducts' => products(line),
102
                                 'type' => 'system'
103
                               })
111 104
        else
112 105
          print "Updating host '#{name}'..." if verbose?
113
=begin
114 106
          @k_system_api.update({
115
                               'id' => @existing[name],
116
                               'host' => {
107
                                 'id' => @existing[line[ORGANIZATION]][name],
117 108
                                 'name' => name,
118
                                 'mac' => namify(line[MACADDRESS], number),
119
                                 'organization_id' => foreman_organization(:name => line[ORGANIZATION]),
120
                                 'environment_id' => foreman_environment(:name => line[ENVIRONMENT]),
121
                                 'operatingsystem_id' => foreman_operatingsystem(:name => line[OPERATINGSYSTEM]),
122
                                 'environment_id' => foreman_environment(:name => line[ENVIRONMENT]),
123
                                 'architecture_id' => foreman_architecture(:name => line[ARCHITECTURE]),
124
                                 'domain_id' => foreman_domain(:name => line[DOMAIN]),
125
                                 'ptable_id' => foreman_partitiontable(:name => line[PARTITIONTABLE])
126
                               }
127
                             }, HEADERS)
128
=end
129
          print "done\n" if verbose?
109
                                 'organization_id' => line[ORGANIZATION],
110
                                 'environment_id' => katello_environment(line[ORGANIZATION], :name => line[ENVIRONMENT]),
111
                                 'content_view_id' => 2, # TODO: katello_contentview(line[ORGANIZATION], :name => line[CONTENTVIEW]),
112
                                 'facts' => facts(line),
113
                                 'installedProducts' => products(line)
114
                               })
130 115
        end
116
        print "done\n" if verbose?
131 117
      end
132 118
    rescue RuntimeError => e
133 119
      raise RuntimeError.new("#{e}\n       #{line}")
134 120
    end
121

  
122
    private
123

  
124
    def facts(line)
125
      facts = {}
126
      facts['cpu.core(s)_per_socket'] = line[CORES]
127
      facts['cpu.cpu_socket(s)'] = line[SOCKETS]
128
      facts['memory.memtotal'] = line[RAM]
129
      facts['uname.machine'] = line[ARCHITECTURE]
130
      if line[OPERATINGSYSTEM].index(' ')
131
        (facts['distribution.name'], facts['distribution.version']) = line[OPERATINGSYSTEM].split(' ')
132
      else
133
        (facts['distribution.name'], facts['distribution.version']) = ['RHEL', line[OPERATINGSYSTEM]]
134
      end
135
      facts
136
    end
137

  
138
    def products(line)
139
      products = CSV.parse_line(line[PRODUCTS]).collect do |product_details|
140
        product = {}
141
        (product[:product_id], product[:productName]) = product_details.split('|')
142
        product
143
      end
144
      products
145
    end
146

  
147
    def subscriptions(line)
148
      subscriptions = CSV.parse_line(line[SUBSCRIPTIONS]).collect do |subscription_details|
149
        subscription = {}
150
        (subscription[:number], subscription[:name]) = subscription_details.split('|')
151
        subscription
152
      end
153
      subscriptions
154
    end
155

  
135 156
  end
136 157

  
137 158
  HammerCLI::MainCommand.subcommand("csv:systems", "import/export systems", HammerCLICsv::SystemsCommand)
test/data/contentviews.csv
1
Name,Count,Organization,Description,Product,Repository
2
Katello,1,megacorp,"Katello - The Sysadmin's Fortress",katello-1.4,katello-1.4
3
Katello,1,megacorp,"Katello - The Sysadmin's Fortress",katello-1.4-client,
test/data/products.csv
1
Name,Count,Organization,Provider,Repository,Repository Type,Repository Url
2
Point of Sale,1,megacorp,MegaCorp,katello-1.4-client,yum,http://fedorapeople.org/groups/katello/releases/yum/1.4-client/RHEL/6Server/x86_64/
3
katello-1.4,1,megacorp,MegaCorp,katello-1.4,yum,http://fedorapeople.org/groups/katello/releases/yum/1.4/RHEL/6Server/x86_64/
test/data/subscriptions.csv
1
Name,Count,Organization,Manifest File
2
MegaCorp,1,megacorp,~/Downloads/megacorp.zip
test/data/systems.csv
1
Name,Count,Organization,Environment,Groups,Virtual,Host,OS,Arch,Sockets,RAM,Cores,SLA,Products,Subscriptions
2
one%d,1,megacorp,Library,Default_Organization_View,Yes,four1,RHEL 6.4,x86_64,1,4,1,Standard,"69|Red Hat Enterprise Linux Server,79|Red Hat Enterprise Linux Server",RH0103708|Red Hat Enterprise Linux Server Premium (8 sockets) (Up to 4 guests)
1
Name,Count,Organization,Environment,Content View,Groups,Virtual,Host,OS,Arch,Sockets,RAM,Cores,SLA,Products,Subscriptions
2
host%d,1,megacorp,Library,Default_Organization_View,,No,,RHEL 6.4,x86_64,1,4,1,Standard,"69|Red Hat Enterprise Linux Server,79|Red Hat Enterprise Linux Server",RH0103708|Red Hat Enterprise Linux Server Premium (8 sockets) (Up to 4 guests)
3
guest%d,1,megacorp,Library,Default_Organization_View,,Yes,host1,RHEL 6.4,x86_64,1,4,1,Standard,"69|Red Hat Enterprise Linux Server,79|Red Hat Enterprise Linux Server",RH0103708|Red Hat Enterprise Linux Server Premium (8 sockets) (Up to 4 guests)
3 4

  

Also available in: Unified diff