Project

General

Profile

Revision c06f1783

Added by Thomas McKay over 6 years ago

fixes #15743 - import and export of subscriptions one-per-line

View differences:

Rakefile
9 9
  print "Cassettes cleared\n"
10 10
end
11 11

  
12
# Rake::TestTask.new do |t|
13
#   t.libs << "lib"
14
#   t.test_files = Dir['test/setup_test.rb'] + Dir.glob('test/**/*_test.rb')
15
#   t.verbose = true
16
# end
17

  
18 12
namespace :test do
19
  [:resources].each do |task_name|
13
  %w(setup resources).each do |task_name|
20 14
    desc "Runs the #{task_name} tests"
21 15
    task task_name do
22 16
      options = {}
......
73 67

  
74 68
desc 'Runs all tests'
75 69
task :test do
70
  Rake::Task['test:setup'].invoke
76 71
  Rake::Task['test:resources'].invoke
77 72
end
78 73

  
lib/hammer_cli_csv/activation_keys.rb
15 15
      AUTOATTACH = "Auto-Attach"
16 16
      SUBSCRIPTIONS = 'Subscriptions'
17 17

  
18
      def export
19
        CSV.open(option_file || '/dev/stdout', 'wb', {:force_quotes => false}) do |csv|
20
          csv << [NAME, ORGANIZATION, DESCRIPTION, LIMIT, ENVIRONMENT, CONTENTVIEW,
21
                  HOSTCOLLECTIONS, AUTOATTACH, SERVICELEVEL, RELEASEVER, SUBSCRIPTIONS]
22
          @api.resource(:organizations).call(:index, {
23
              :per_page => 999999
24
          })['results'].each do |organization|
25
            next if option_organization && organization['name'] != option_organization
26

  
27
            @api.resource(:activation_keys).call(:index, {
28
                'per_page' => 999999,
29
                'organization_id' => organization['id']
30
            })['results'].each do |activationkey|
31
              name = namify(activationkey['name'])
32
              count = 1
33
              description = activationkey['description']
34
              limit = activationkey['unlimited_content_hosts'] ? 'Unlimited' : activationkey['max_content_hosts']
35
              environment = activationkey['environment']['label']
36
              contentview = activationkey['content_view']['name']
37
              hostcollections = export_column(activationkey, 'host_collections', 'name')
38
              autoattach = activationkey['auto_attach'] ? 'Yes' : 'No'
39
              servicelevel = activationkey['service_level']
40
              releasever = activationkey['release_version']
41
              subscriptions = CSV.generate do |column|
42
                column << @api.resource(:subscriptions).call(:index, {
43
                              'organization_id' => organization['id'],
44
                              'activation_key_id' => activationkey['id']
45
                          })['results'].collect do |subscription|
46
                  amount = subscription['amount'] == 0 ? 'Automatic' : subscription['amount']
47
                  sku = subscription['product_id'].match(/\A[0-9]/) ? 'Custom' : subscription['product_id']
48
                  "#{amount}|#{sku}|#{subscription['product_name']}"
49
                end
18
      def export(csv)
19
        csv << [NAME, ORGANIZATION, DESCRIPTION, LIMIT, ENVIRONMENT, CONTENTVIEW,
20
                HOSTCOLLECTIONS, AUTOATTACH, SERVICELEVEL, RELEASEVER, SUBSCRIPTIONS]
21
        @api.resource(:organizations).call(:index, {
22
            :per_page => 999999
23
        })['results'].each do |organization|
24
          next if option_organization && organization['name'] != option_organization
25

  
26
          @api.resource(:activation_keys).call(:index, {
27
              'per_page' => 999999,
28
              'organization_id' => organization['id']
29
          })['results'].each do |activationkey|
30
            name = namify(activationkey['name'])
31
            count = 1
32
            description = activationkey['description']
33
            limit = activationkey['unlimited_content_hosts'] ? 'Unlimited' : activationkey['max_content_hosts']
34
            environment = activationkey['environment']['label']
35
            contentview = activationkey['content_view']['name']
36
            hostcollections = export_column(activationkey, 'host_collections', 'name')
37
            autoattach = activationkey['auto_attach'] ? 'Yes' : 'No'
38
            servicelevel = activationkey['service_level']
39
            releasever = activationkey['release_version']
40
            subscriptions = CSV.generate do |column|
41
              column << @api.resource(:subscriptions).call(:index, {
42
                            'organization_id' => organization['id'],
43
                            'activation_key_id' => activationkey['id']
44
                        })['results'].collect do |subscription|
45
                amount = subscription['amount'] == 0 ? 'Automatic' : subscription['amount']
46
                sku = subscription['product_id'].match(/\A[0-9]/) ? 'Custom' : subscription['product_id']
47
                "#{amount}|#{sku}|#{subscription['product_name']}"
50 48
              end
51
              subscriptions.delete!("\n")
52
              csv << [name, count, organization['name'], description, limit, environment, contentview,
53
                      hostcollections, servicelevel, releasever, autoattach, subscriptions]
54 49
            end
50
            subscriptions.delete!("\n")
51
            csv << [name, count, organization['name'], description, limit, environment, contentview,
52
                    hostcollections, servicelevel, releasever, autoattach, subscriptions]
55 53
          end
56 54
        end
57 55
      end
lib/hammer_cli_csv/architectures.rb
6 6

  
7 7
      OPERATINGSYSTEMS = 'Operating Systems'
8 8

  
9
      def export
10
        CSV.open(option_file || '/dev/stdout', 'wb', {:force_quotes => true}) do |csv|
11
          csv << [NAME, OPERATINGSYSTEMS]
12
          @api.resource(:architectures).call(:index, {:per_page => 999999})['results'].each do |architecture|
13
            architecture = @api.resource(:architectures).call(:show, {:id => architecture['id']})
14
            name = architecture['name']
15
            operatingsystems = export_column(architecture, 'operatingsystems', 'title')
16
            csv << [name, operatingsystems]
17
          end
9
      def export(csv)
10
        csv << [NAME, OPERATINGSYSTEMS]
11
        @api.resource(:architectures).call(:index, {:per_page => 999999})['results'].each do |architecture|
12
          architecture = @api.resource(:architectures).call(:show, {:id => architecture['id']})
13
          name = architecture['name']
14
          operatingsystems = export_column(architecture, 'operatingsystems', 'title')
15
          csv << [name, operatingsystems]
18 16
        end
19 17
      end
20 18

  
lib/hammer_cli_csv/base.rb
74 74
                                       })
75 75
      end
76 76

  
77
      option_export? ? export : import
77
      if option_export?
78
        if option_file
79
          CSV.open(option_file, 'wb', {:force_quotes => false}) do |csv|
80
            export csv
81
          end
82
        else
83
          CSV do |csv|
84
            export csv
85
          end
86
        end
87
      else
88
        import
89
      end
78 90
      HammerCLI::EX_OK
79 91
    end
80 92

  
lib/hammer_cli_csv/compute_profiles.rb
12 12
      URL = 'URL'
13 13

  
14 14
      def export
15
        CSV.open(option_file || '/dev/stdout', 'wb', {:force_quotes => true}) do |csv|
16
          csv << [NAME, ORGANIZATIONS, LOCATIONS, DESCRIPTION, PROVIDER, URL]
17
          @api.resource(:compute_profiles).call(:index, {:per_page => 999999})['results'].each do |compute_profile|
18
            puts compute_profile
19
            compute_profile = @api.resource(:compute_profiles).call(:show, {'id' => compute_profile['id']})
20
            name = compute_profile['name']
21
            organizations = export_column(compute_profile, 'organizations', 'name')
22
            locations = export_column(compute_profile, 'locations', 'name')
23
            description = compute_profile['description']
24
            provider = compute_profile['provider']
25
            url = compute_profile['url']
26
            csv << [name, organizations, locations, description, provider, url]
27
          end
15
        csv << [NAME, ORGANIZATIONS, LOCATIONS, DESCRIPTION, PROVIDER, URL]
16
        @api.resource(:compute_profiles).call(:index, {:per_page => 999999})['results'].each do |compute_profile|
17
          puts compute_profile
18
          compute_profile = @api.resource(:compute_profiles).call(:show, {'id' => compute_profile['id']})
19
          name = compute_profile['name']
20
          organizations = export_column(compute_profile, 'organizations', 'name')
21
          locations = export_column(compute_profile, 'locations', 'name')
22
          description = compute_profile['description']
23
          provider = compute_profile['provider']
24
          url = compute_profile['url']
25
          csv << [name, organizations, locations, description, provider, url]
28 26
        end
29 27
      end
30 28

  
lib/hammer_cli_csv/compute_resources.rb
14 14
      PROVIDER = 'Provider'
15 15
      URL = 'URL'
16 16

  
17
      def export
18
        CSV.open(option_file || '/dev/stdout', 'wb', {:force_quotes => true}) do |csv|
19
          csv << [NAME, ORGANIZATIONS, LOCATIONS, DESCRIPTION, PROVIDER, URL]
20
          @api.resource(:compute_resources).call(:index, {:per_page => 999999})['results'].each do |compute_resource|
21
            compute_resource = @api.resource(:compute_resources).call(:show, {'id' => compute_resource['id']})
17
      def export(csv)
18
        csv << [NAME, ORGANIZATIONS, LOCATIONS, DESCRIPTION, PROVIDER, URL]
19
        @api.resource(:compute_resources).call(:index, {:per_page => 999999})['results'].each do |compute_resource|
20
          compute_resource = @api.resource(:compute_resources).call(:show, {'id' => compute_resource['id']})
22 21

  
23
            name = compute_resource['name']
24
            organizations = export_column(compute_resource, 'organizations', 'name')
25
            locations = export_column(compute_resource, 'locations', 'name')
26
            description = compute_resource['description']
27
            provider = compute_resource['provider']
28
            url = compute_resource['url']
29
            csv << [name, organizations, locations, description, provider, url]
30
          end
22
          name = compute_resource['name']
23
          organizations = export_column(compute_resource, 'organizations', 'name')
24
          locations = export_column(compute_resource, 'locations', 'name')
25
          description = compute_resource['description']
26
          provider = compute_resource['provider']
27
          url = compute_resource['url']
28
          csv << [name, organizations, locations, description, provider, url]
31 29
        end
32 30
      end
33 31

  
lib/hammer_cli_csv/containers.rb
11 11
      ENTRYPOINT = 'Entry Point'
12 12
      COMMAND = 'Command'
13 13

  
14
      def export
15
        CSV.open(option_file || '/dev/stdout', 'wb') do |csv|
16
          csv << [NAME, REGISTRY, REPOSITORY, COMPUTERESOURCE, ATTACH, ENTRYPOINT, COMMAND]
17
          @api.resource(:containers).call(:index, {'per_page' => 999999})['results'].each do |container|
18
            csv << [container['name'],
19
                    container['registry_name'],
20
                    "#{container['repository_name']}:#{container['tag']}",
21
                    container['compute_resource_name'],
22
                    export_attach_types(container),
23
                    container['entrypoint'],
24
                    container['command']]
25
          end
14
      def export(csv)
15
        csv << [NAME, REGISTRY, REPOSITORY, COMPUTERESOURCE, ATTACH, ENTRYPOINT, COMMAND]
16
        @api.resource(:containers).call(:index, {'per_page' => 999999})['results'].each do |container|
17
          csv << [container['name'],
18
                  container['registry_name'],
19
                  "#{container['repository_name']}:#{container['tag']}",
20
                  container['compute_resource_name'],
21
                  export_attach_types(container),
22
                  container['entrypoint'],
23
                  container['command']]
26 24
        end
27 25
      end
28 26

  
lib/hammer_cli_csv/content_hosts.rb
6 6
      command_name 'content-hosts'
7 7
      desc         'import or export content hosts'
8 8

  
9
      def self.supported?
10
        true
11
      end
12

  
13
      option %w(--subscriptions-only), :flag, 'Export only detailed subscription information'
14

  
9 15
      ORGANIZATION = 'Organization'
10 16
      ENVIRONMENT = 'Environment'
11 17
      CONTENTVIEW = 'Content View'
......
20 26
      SLA = 'SLA'
21 27
      PRODUCTS = 'Products'
22 28
      SUBSCRIPTIONS = 'Subscriptions'
29
      SUBS_NAME = 'Subscription Name'
30
      SUBS_TYPE = 'Subscription Type'
31
      SUBS_QUANTITY = 'Subscription Quantity'
32
      SUBS_SKU = 'Subscription SKU'
33
      SUBS_CONTRACT = 'Subscription Contract'
34
      SUBS_ACCOUNT = 'Subscription Account'
35
      SUBS_START = 'Subscription Start'
36
      SUBS_END = 'Subscription End'
23 37

  
24
      def export
25
        CSV.open(option_file || '/dev/stdout', 'wb', {:force_quotes => false}) do |csv|
26
          csv << [NAME, ORGANIZATION, ENVIRONMENT, CONTENTVIEW, HOSTCOLLECTIONS, VIRTUAL, HOST,
27
                  OPERATINGSYSTEM, ARCHITECTURE, SOCKETS, RAM, CORES, SLA, PRODUCTS, SUBSCRIPTIONS]
28
          export_katello csv
38
      def export(csv)
39
        if option_subscriptions_only?
40
          export_subscriptions csv
41
        else
42
          export_all csv
29 43
        end
30 44
      end
31 45

  
32
      def export_katello(csv)
33
        @api.resource(:organizations).call(:index, {:per_page => 999999})['results'].each do |organization|
34
          next if option_organization && organization['name'] != option_organization
35

  
36
          @api.resource(:hosts).call(:index, {
37
              'per_page' => 999999,
38
              'organization_id' => foreman_organization(:name => organization['name'])
39
          })['results'].each do |host|
40
            host = @api.resource(:hosts).call(:show, {
41
                'id' => host['id']
42
            })
43
            host['facts'] ||= {}
44

  
45
            name = host['name']
46
            organization_name = organization['name']
47
            if host['content_facet_attributes']
48
              environment = host['content_facet_attributes']['lifecycle_environment']['name']
49
              contentview = host['content_facet_attributes']['content_view']['name']
50
              hostcollections = export_column(host['content_facet_attributes'], 'host_collections', 'name')
46
      def export_subscriptions(csv)
47
        csv << shared_headers + [SUBS_NAME, SUBS_TYPE, SUBS_QUANTITY, SUBS_SKU,
48
                                 SUBS_CONTRACT, SUBS_ACCOUNT, SUBS_START, SUBS_END]
49
        iterate_hosts(csv) do |host|
50
          export_line = shared_columns(host)
51
          if host['subscription_facet_attributes']
52
            subscriptions = @api.resource(:host_subscriptions).call(:index, {
53
                'organization_id' => host['organization_id'],
54
                'host_id' => host['id']
55
            })['results']
56
            if subscriptions.empty?
57
              csv << export_line + [nil, nil, nil, nil, nil, nil]
51 58
            else
52
              environment = nil
53
              contentview = nil
54
              hostcollections = nil
59
              subscriptions.each do |subscription|
60
                subscription_type = subscription['product_id'].to_i == 0 ? 'Red Hat' : 'Custom'
61
                subscription_type += ' Guest' if subscription['type'] == 'STACK_DERIVED'
62
                subscription_type += ' Temporary' if subscription['type'] == 'UNMAPPED_GUEST'
63
                csv << export_line + [subscription['product_name'], subscription_type,
64
                                      subscription['quantity_consumed'], subscription['product_id'],
65
                                      subscription['contract_number'], subscription['account_number'],
66
                                      DateTime.parse(subscription['start_date']).strftime('%m/%d/%Y'),
67
                                      DateTime.parse(subscription['end_date']).strftime('%m/%d/%Y')]
68
              end
55 69
            end
56
            virtual = host['facts']['virt::is_guest'] == 'true' ? 'Yes' : 'No'
57
            hypervisor_host = host['subscription_facet_attributes']['virtual_host'].nil? ? nil : host['subscription_facet_attributes']['virtual_host']['name']
58
            operatingsystem = host['facts']['distribution::name'] if host['facts']['distribution::name']
59
            operatingsystem += " #{host['facts']['distribution::version']}" if host['facts']['distribution::version']
60
            architecture = host['facts']['uname::machine']
61
            sockets = host['facts']['cpu::cpu_socket(s)']
62
            ram = host['facts']['memory::memtotal']
63
            cores = host['facts']['cpu::core(s)_per_socket'] || 1
64
            sla = ''
65
            products = export_column(host['subscription_facet_attributes'], 'installed_products', 'productName')
70
          else
71
            csv << export_line + [nil, nil, nil, nil, nil, nil]
72
          end
73
        end
74
      end
75

  
76
      def export_all(csv)
77
        csv << shared_headers + [SUBSCRIPTIONS]
78
        iterate_hosts(csv) do |host|
79
          if host['subscription_facet_attributes']
66 80
            subscriptions = CSV.generate do |column|
67 81
              column << @api.resource(:host_subscriptions).call(:index, {
68
                  'organization_id' => organization['id'],
82
                  'organization_id' => host['organization_id'],
69 83
                  'host_id' => host['id']
70 84
              })['results'].collect do |subscription|
71 85
                "#{subscription['quantity_consumed']}"\
......
75 89
              end
76 90
            end
77 91
            subscriptions.delete!("\n")
78
            csv << [name, organization_name, environment, contentview, hostcollections, virtual, hypervisor_host,
79
                    operatingsystem, architecture, sockets, ram, cores, sla, products, subscriptions]
92
          else
93
            subscriptions = nil
80 94
          end
95

  
96
          csv << shared_columns(host) + [subscriptions]
81 97
        end
82 98
      end
83 99

  
......
99 115
      def import_locally
100 116
        @existing = {}
101 117
        @hypervisor_guests = {}
118
        @all_subscriptions = {}
102 119

  
103 120
        thread_import do |line|
104 121
          create_from_csv(line)
......
111 128
              'id' => host_id,
112 129
              'host' => {
113 130
                'subscription_facet_attributes' => {
131
                  'autoheal' => false,
114 132
                  'hypervisor_guest_uuids' => guest_ids
115 133
                }
116 134
              }
......
128 146
        count(line[COUNT]).times do |number|
129 147
          name = namify(line[NAME], number)
130 148

  
131
          if !@existing.include? name
132
            print(_("Creating content host '%{name}'...") % {:name => name}) if option_verbose?
133
            params = {
134
              'name' => name,
135
              'facts' => facts(name, line),
136
              'lifecycle_environment_id' => lifecycle_environment(line[ORGANIZATION], :name => line[ENVIRONMENT]),
137
              'content_view_id' => katello_contentview(line[ORGANIZATION], :name => line[CONTENTVIEW]),
138
              'installed_products' => products(line),
139
              'service_level' => line[SLA]
140
            }
141
            host = @api.resource(:host_subscriptions).call(:create, params)
142
            @existing[name] = host['id']
149
          if option_subscriptions_only?
150
            update_subscriptions_only(name, line)
143 151
          else
144
            print(_("Updating content host '%{name}'...") % {:name => name}) if option_verbose?
145
            params = {
146
              'id' => @existing[name],
147
              'host' => {
148
                'content_facet_attributes' => {
149
                  'lifecycle_environment_id' => lifecycle_environment(line[ORGANIZATION], :name => line[ENVIRONMENT]),
150
                  'content_view_id' => katello_contentview(line[ORGANIZATION], :name => line[CONTENTVIEW])
151
                },
152
                'subscription_facet_attributes' => {
153
                  'facts' => facts(name, line),
154
                  'installed_products' => products(line),
155
                  'service_level' => line[SLA]
156
                }
157
              }
158
            }
159
            host = @api.resource(:hosts).call(:update, params)
152
            update_or_create(name, line)
160 153
          end
154
        end
155
      end
161 156

  
162
          if line[VIRTUAL] == 'Yes' && line[HOST]
163
            raise "Content host '#{line[HOST]}' not found" if !@existing[line[HOST]]
164
            @hypervisor_guests[@existing[line[HOST]]] ||= []
165
            @hypervisor_guests[@existing[line[HOST]]] << "#{line[ORGANIZATION]}/#{name}"
166
          end
157
      private
167 158

  
168
          update_host_collections(host, line)
169
          update_subscriptions(host, line)
159
      def update_subscriptions_only(name, line)
160
        raise _("Content host '%{name}' must already exist with --subscriptions-only") % {:name => name} unless @existing.include? name
170 161

  
171
          puts _('done') if option_verbose?
162
        print(_("Updating subscriptions for content host '%{name}'...") % {:name => name}) if option_verbose?
163
        host = @api.resource(:hosts).call(:show, {:id => @existing[name]})
164
        update_subscriptions(host, line, false)
165
        puts _('done') if option_verbose?
166
      end
167

  
168
      def update_or_create(name, line)
169
        if !@existing.include? name
170
          print(_("Creating content host '%{name}'...") % {:name => name}) if option_verbose?
171
          params = {
172
            'name' => name,
173
            'facts' => facts(name, line),
174
            'lifecycle_environment_id' => lifecycle_environment(line[ORGANIZATION], :name => line[ENVIRONMENT]),
175
            'content_view_id' => katello_contentview(line[ORGANIZATION], :name => line[CONTENTVIEW])
176
          }
177
          params['installed_products'] = products(line) if line[PRODUCTS]
178
          params['service_level'] = line[SLA] if line[SLA]
179
          host = @api.resource(:host_subscriptions).call(:create, params)
180
          @existing[name] = host['id']
181
        else
182
          print(_("Updating content host '%{name}'...") % {:name => name}) if option_verbose?
183
          params = {
184
            'id' => @existing[name],
185
            'host' => {
186
              'content_facet_attributes' => {
187
                'lifecycle_environment_id' => lifecycle_environment(line[ORGANIZATION], :name => line[ENVIRONMENT]),
188
                'content_view_id' => katello_contentview(line[ORGANIZATION], :name => line[CONTENTVIEW])
189
              },
190
              'subscription_facet_attributes' => {
191
                'facts' => facts(name, line),
192
                'installed_products' => products(line),
193
                'service_level' => line[SLA]
194
              }
195
            }
196
          }
197
          host = @api.resource(:hosts).call(:update, params)
198
        end
199

  
200
        if line[VIRTUAL] == 'Yes' && line[HOST]
201
          raise "Content host '#{line[HOST]}' not found" if !@existing[line[HOST]]
202
          @hypervisor_guests[@existing[line[HOST]]] ||= []
203
          @hypervisor_guests[@existing[line[HOST]]] << "#{line[ORGANIZATION]}/#{name}"
172 204
        end
205

  
206
        update_host_collections(host, line)
207
        update_subscriptions(host, line, true)
208

  
209
        puts _('done') if option_verbose?
173 210
      rescue RuntimeError => e
174 211
        raise "#{e}\n       #{line}"
175 212
      end
176 213

  
177
      private
178

  
179 214
      def facts(name, line)
180 215
        facts = {}
181 216
        facts['system.certificate_version'] = '3.2'  # Required for auto-attach to work
......
192 227
      end
193 228

  
194 229
      def update_host_collections(host, line)
195
        return nil if !line[HOSTCOLLECTIONS]
196
        CSV.parse_line(line[HOSTCOLLECTIONS]).each do |hostcollection_name|
197
          @api.resource(:host_collections).call(:add_hosts, {
198
              'id' => katello_hostcollection(line[ORGANIZATION], :name => hostcollection_name),
199
              'host_ids' => [host['id']]
200
          })
201
        end
230
        # TODO: http://projects.theforeman.org/issues/16234
231
        # return nil if line[HOSTCOLLECTIONS].nil? || line[HOSTCOLLECTIONS].empty?
232
        # CSV.parse_line(line[HOSTCOLLECTIONS]).each do |hostcollection_name|
233
        #   @api.resource(:host_collections).call(:add_hosts, {
234
        #       'id' => katello_hostcollection(line[ORGANIZATION], :name => hostcollection_name),
235
        #       'host_ids' => [host['id']]
236
        #   })
237
        # end
202 238
      end
203 239

  
204 240
      def os_name_version(operatingsystem)
......
224 260
        end
225 261
      end
226 262

  
227
      def update_subscriptions(host, line)
263
      def update_subscriptions(host, line, remove_existing)
228 264
        existing_subscriptions = @api.resource(:host_subscriptions).call(:index, {
229 265
            'host_id' => host['id']
230 266
        })['results']
231
        if existing_subscriptions.length != 0
267
        if remove_existing && existing_subscriptions.length != 0
268
          existing_subscriptions.map! do |existing_subscription|
269
            {:id => existing_subscription['id'], :quantity => existing_subscription['quantity_consumed']}
270
          end
232 271
          @api.resource(:host_subscriptions).call(:remove_subscriptions, {
233 272
            'host_id' => host['id'],
234 273
            'subscriptions' => existing_subscriptions
235 274
          })
275
          existing_subscriptions = []
276
        end
277

  
278
        if line[SUBS_NAME].nil? && line[SUBS_SKU].nil?
279
          all_in_one_subscription(host, existing_subscriptions, line)
280
        else
281
          single_subscription(host, existing_subscriptions, line)
236 282
        end
283
      end
284

  
285
      def single_subscription(host, existing_subscriptions, line)
286
        already_attached = false
287
        if line[SUBS_SKU]
288
          already_attached = existing_subscriptions.detect do |subscription|
289
            line[SUBS_SKU] == subscription['product_id']
290
          end
291
        elsif line[SUBS_NAME]
292
          already_attached = existing_subscriptions.detect do |subscription|
293
            line[SUBS_NAME] == subscription['name']
294
          end
295
        end
296
        if already_attached
297
          print _(" '%{name}' already attached...") % {:name => already_attached['name']}
298
          return
299
        end
300

  
301
        available_subscriptions = @api.resource(:subscriptions).call(:index, {
302
          'organization_id' => host['organization_id'],
303
          'host_id' => host['id'],
304
          'available_for' => 'host',
305
          'match_host' => true
306
        })['results']
307

  
308
        matches = matches_by_sku_and_name([], line, available_subscriptions)
309
        matches = matches_by_type(matches, line)
310
        matches = matches_by_account(matches, line)
311
        matches = matches_by_contract(matches, line)
312
        matches = matches_by_quantity(matches, line)
237 313

  
314
        raise _("No matching subscriptions") if matches.empty?
315

  
316
        match = matches[0]
317
        print _(" attaching '%{name}'...") % {:name => match['name']} if option_verbose?
318

  
319
        @api.resource(:host_subscriptions).call(:add_subscriptions, {
320
            'host_id' => host['id'],
321
            'subscriptions' => existing_subscriptions + [match]
322
        })
323
      end
324

  
325
      def all_in_one_subscription(host, existing_subscriptions, line)
238 326
        return if line[SUBSCRIPTIONS].nil? || line[SUBSCRIPTIONS].empty?
239 327

  
240 328
        subscriptions = CSV.parse_line(line[SUBSCRIPTIONS], {:skip_blanks => true}).collect do |details|
......
274 362
          end
275 363
        end
276 364
      end
365

  
366
      def get_all_subscriptions(organization)
367
        @api.resource(:subscriptions).call(:index, {
368
            :per_page => 999999,
369
            'organization_id' => foreman_organization(:name => organization)
370
        })['results']
371
      end
372

  
373
      def iterate_hosts(csv)
374
        hypervisors = []
375
        hosts = []
376
        @api.resource(:organizations).call(:index, {:per_page => 999999})['results'].each do |organization|
377
          next if option_organization && organization['name'] != option_organization
378

  
379
          @api.resource(:hosts).call(:index, {
380
              'per_page' => 999999,
381
              'organization_id' => foreman_organization(:name => organization['name'])
382
          })['results'].each do |host|
383
            host = @api.resource(:hosts).call(:show, {
384
                'id' => host['id']
385
            })
386
            host['facts'] ||= {}
387
            if host['subscription_facet_attributes']['virtual_guests'].empty?
388
              hosts.push(host)
389
            else
390
              hypervisors.push(host)
391
            end
392
          end
393
        end
394
        hypervisors.each do |host|
395
          yield host
396
        end
397
        hosts.each do |host|
398
          yield host
399
        end
400
      end
401

  
402
      def shared_headers
403
        [NAME, ORGANIZATION, ENVIRONMENT, CONTENTVIEW, HOSTCOLLECTIONS, VIRTUAL, HOST,
404
         OPERATINGSYSTEM, ARCHITECTURE, SOCKETS, RAM, CORES, SLA, PRODUCTS]
405
      end
406

  
407
      def shared_columns(host)
408
        name = host['name']
409
        organization_name = host['organization_name']
410
        if host['content_facet_attributes']
411
          environment = host['content_facet_attributes']['lifecycle_environment']['name']
412
          contentview = host['content_facet_attributes']['content_view']['name']
413
          hostcollections = export_column(host['content_facet_attributes'], 'host_collections', 'name')
414
        else
415
          environment = nil
416
          contentview = nil
417
          hostcollections = nil
418
        end
419
        if host['subscription_facet_attributes']
420
          hypervisor_host = host['subscription_facet_attributes']['virtual_host'].nil? ? nil : host['subscription_facet_attributes']['virtual_host']['name']
421
          products = export_column(host['subscription_facet_attributes'], 'installed_products') do |product|
422
            "#{product['productId']}|#{product['productName']}"
423
          end
424
        else
425
          hypervisor_host = nil
426
          products = nil
427
        end
428
        virtual = host['facts']['virt::is_guest'] == 'true' ? 'Yes' : 'No'
429
        operatingsystem = host['facts']['distribution::name'] if host['facts']['distribution::name']
430
        operatingsystem += " #{host['facts']['distribution::version']}" if host['facts']['distribution::version']
431
        architecture = host['facts']['uname::machine']
432
        sockets = host['facts']['cpu::cpu_socket(s)']
433
        ram = host['facts']['memory::memtotal']
434
        cores = host['facts']['cpu::core(s)_per_socket'] || 1
435
        sla = ''
436

  
437
        [name, organization_name, environment, contentview, hostcollections, virtual, hypervisor_host,
438
         operatingsystem, architecture, sockets, ram, cores, sla, products]
439
      end
440

  
441
      def matches_by_sku_and_name(matches, line, subscriptions)
442
        if line[SUBS_SKU]
443
          matches = subscriptions.select do |subscription|
444
            line[SUBS_SKU] == subscription['product_id']
445
          end
446
          raise _("No subscriptions match SKU '%{sku}'") % {:sku => line[SUBS_SKU]} if matches.empty?
447
        elsif line[SUBS_NAME]
448
          matches = subscriptions.select do |subscription|
449
            line[SUBS_NAME] == subscription['name']
450
          end
451
          raise _("No subscriptions match name '%{name}'") % {:name => line[SUBS_NAME]} if matches.empty?
452
        end
453
        matches
454
      end
455

  
456
      def matches_by_type(matches, line)
457
        if line[SUBS_TYPE] == 'Red Hat' || line[SUBS_TYPE] == 'Custom'
458
          matches = matches.select do |subscription|
459
            subscription['type'] == 'NORMAL'
460
          end
461
        elsif line[SUBS_TYPE] == 'Red Hat Guest'
462
          matches = matches.select do |subscription|
463
            subscription['type'] == 'STACK_DERIVED'
464
          end
465
        elsif line[SUBS_TYPE] == 'Red Hat Temporary'
466
          matches = matches.select do |subscription|
467
            subscription['type'] == 'UNMAPPED_GUEST'
468
          end
469
        end
470
        raise _("No subscriptions match type '%{type}'") % {:type => line[SUBS_TYPE]} if matches.empty?
471
        matches
472
      end
473

  
474
      def matches_by_account(matches, line)
475
        if matches.length > 1 && line[SUBS_ACCOUNT]
476
          refined = matches.select do |subscription|
477
            line[SUBS_ACCOUNT] == subscription['account_number']
478
          end
479
          matches = refined unless refined.empty?
480
        end
481
        matches
482
      end
483

  
484
      def matches_by_contract(matches, line)
485
        if matches.length > 1 && line[SUBS_CONTRACT]
486
          refined = matches.select do |subscription|
487
            line[SUBS_CONTRACT] == subscription['contract_number']
488
          end
489
          matches = refined unless refined.empty?
490
        end
491
        matches
492
      end
493

  
494
      def matches_by_quantity(matches, line)
495
        if line[SUBS_QUANTITY] && line[SUBS_QUANTITY] != 'Automatic'
496
          refined = matches.select do |subscription|
497
            subscription['available'] == -1 || line[SUBS_QUANTITY].to_i <= subscription['available']
498
          end
499
          raise _("No '%{name}' subscription with quantity %{quantity} or more available") %
500
                    {:name => matches[0]['name'], :quantity => line[SUBS_QUANTITY]} if refined.empty?
501
          matches = refined
502
        end
503
        matches
504
      end
277 505
    end
278 506
  end
279 507
end
lib/hammer_cli_csv/content_view_filters.rb
14 14
      REPOSITORIES = 'Repositories'
15 15
      RULES = 'Rules'
16 16

  
17
      def export
18
        CSV.open(option_file || '/dev/stdout', 'wb', {:force_quotes => false}) do |csv|
19
          csv << [NAME, CONTENTVIEW, ORGANIZATION, TYPE, DESCRIPTION, REPOSITORIES, RULES]
20
          @api.resource(:organizations).call(:index, {
21
              :per_page => 999999
22
          })['results'].each do |organization|
23
            next if option_organization && organization['name'] != option_organization
24

  
25
            @api.resource(:content_views).call(:index, {
26
                'per_page' => 999999,
27
                'organization_id' => organization['id'],
28
                'nondefault' => true
29
            })['results'].each do |contentview|
30
              @api.resource(:content_view_filters).call(:index, {
31
                  'content_view_id' => contentview['id']
32
              })['results'].collect do |filter|
33
                filter_type = "#{filter['inclusion'] == true ? 'Include' : 'Exclude'} #{export_filter_type(filter['type'])}"
34

  
35
                rules = nil
36
                case filter['type']
37
                when /rpm/
38
                  rules = export_rpm_rules(filter)
39
                when /erratum/
40
                  rules = export_erratum_rules(filter)
41
                when /package_group/
42
                  rules = export_package_group_rules(filter)
43
                else
44
                  raise "Unknown filter rule type '#{filter['type']}'"
45
                end
46

  
47
                name = filter['name']
48
                repositories = export_column(filter, 'repositories', 'name')
49
                csv << [name, contentview['name'], organization['name'], filter_type, filter['description'],
50
                        repositories, rules]
17
      def export(csv)
18
        csv << [NAME, CONTENTVIEW, ORGANIZATION, TYPE, DESCRIPTION, REPOSITORIES, RULES]
19
        @api.resource(:organizations).call(:index, {
20
            :per_page => 999999
21
        })['results'].each do |organization|
22
          next if option_organization && organization['name'] != option_organization
23

  
24
          @api.resource(:content_views).call(:index, {
25
              'per_page' => 999999,
26
              'organization_id' => organization['id'],
27
              'nondefault' => true
28
          })['results'].each do |contentview|
29
            @api.resource(:content_view_filters).call(:index, {
30
                'content_view_id' => contentview['id']
31
            })['results'].collect do |filter|
32
              filter_type = "#{filter['inclusion'] == true ? 'Include' : 'Exclude'} #{export_filter_type(filter['type'])}"
33

  
34
              rules = nil
35
              case filter['type']
36
              when /rpm/
37
                rules = export_rpm_rules(filter)
38
              when /erratum/
39
                rules = export_erratum_rules(filter)
40
              when /package_group/
41
                rules = export_package_group_rules(filter)
42
              else
43
                raise "Unknown filter rule type '#{filter['type']}'"
51 44
              end
45

  
46
              name = filter['name']
47
              repositories = export_column(filter, 'repositories', 'name')
48
              csv << [name, contentview['name'], organization['name'], filter_type, filter['description'],
49
                      repositories, rules]
52 50
            end
53 51
          end
54 52
        end
lib/hammer_cli_csv/content_views.rb
16 16
      REPOSITORIES = 'Repositories or Composites'
17 17
      ENVIRONMENTS = "Lifecycle Environments"
18 18

  
19
      def export
20
        CSV.open(option_file || '/dev/stdout', 'wb', {:force_quotes => false}) do |csv|
21
          csv << [NAME, LABEL, ORGANIZATION, COMPOSITE, REPOSITORIES, ENVIRONMENTS]
22
          @api.resource(:organizations).call(:index, {
23
              :per_page => 999999
24
          })['results'].each do |organization|
25
            next if option_organization && organization['name'] != option_organization
26

  
27
            composite_contentviews = []
28
            @api.resource(:content_views).call(:index, {
29
                'per_page' => 999999,
30
                'organization_id' => organization['id'],
31
                'nondefault' => true
32
            })['results'].each do |contentview|
33
              name = contentview['name']
34
              label = contentview['label']
35
              orgname = organization['name']
36
              environments = CSV.generate do |column|
37
                column << environment_names(contentview)
38
              end
39
              environments.delete!("\n")
40
              composite = contentview['composite'] == true ? 'Yes' : 'No'
41
              if composite == 'Yes'
42
                contentviews = CSV.generate do |column|
43
                  column << contentview['components'].collect do |component|
44
                    component['content_view']['name']
45
                  end
19
      def export(csv)
20
        csv << [NAME, LABEL, ORGANIZATION, COMPOSITE, REPOSITORIES, ENVIRONMENTS]
21
        @api.resource(:organizations).call(:index, {
22
            :per_page => 999999
23
        })['results'].each do |organization|
24
          next if option_organization && organization['name'] != option_organization
25

  
26
          composite_contentviews = []
27
          @api.resource(:content_views).call(:index, {
28
              'per_page' => 999999,
29
              'organization_id' => organization['id'],
30
              'nondefault' => true
31
          })['results'].each do |contentview|
32
            name = contentview['name']
33
            label = contentview['label']
34
            orgname = organization['name']
35
            environments = CSV.generate do |column|
36
              column << environment_names(contentview)
37
            end
38
            environments.delete!("\n")
39
            composite = contentview['composite'] == true ? 'Yes' : 'No'
40
            if composite == 'Yes'
41
              contentviews = CSV.generate do |column|
42
                column << contentview['components'].collect do |component|
43
                  component['content_view']['name']
46 44
                end
47
                contentviews.delete!("\n")
48
                composite_contentviews << [name, 1, label, orgname, composite, contentviews, environments]
49
              else
50
                repositories = export_column(contentview, 'repositories', 'name')
51
                csv << [name, label, orgname, composite, repositories, environments]
52 45
              end
46
              contentviews.delete!("\n")
47
              composite_contentviews << [name, 1, label, orgname, composite, contentviews, environments]
48
            else
49
              repositories = export_column(contentview, 'repositories', 'name')
50
              csv << [name, label, orgname, composite, repositories, environments]
53 51
            end
54
            composite_contentviews.each do |contentview|
55
              csv << contentview
56
            end
52
          end
53
          composite_contentviews.each do |contentview|
54
            csv << contentview
57 55
          end
58 56
        end
59 57
      end
lib/hammer_cli_csv/domains.rb
12 12

  
13 13
      SEPARATOR = ' = '
14 14

  
15
      def export
16
        CSV.open(option_file || '/dev/stdout', 'wb', {:force_quotes => true}) do |csv|
17
          csv << [NAME, ORGANIZATIONS, LOCATIONS, DESCRIPTION, SMART_PROXY, PARAMETERS]
18
          search_options = {:per_page => 999999}
19
          search_options['search'] = "organization=\"#{option_organization}\"" if option_organization
20
          @api.resource(:domains).call(:index, search_options)['results'].each do |domain|
21
            domain = @api.resource(:domains).call(:show, {'id' => domain['id']})
22
            raise "Domain 'id=#{domain['id']}' not found" if !domain || domain.empty?
23

  
24
            name = domain['name']
25
            organizations = option_organization ? option_organization : export_column(domain, 'organizations', 'name')
26
            locations = export_column(domain, 'locations', 'name')
27
            description = domain['fullname']
28
            capsule = foreman_smart_proxy(:id => domain['dns_id'])
29
            parameters = export_parameters(domain['parameters'])
30
            csv << [name, organizations, locations, description, capsule, parameters]
31
          end
15
      def export(csv)
16
        csv << [NAME, ORGANIZATIONS, LOCATIONS, DESCRIPTION, SMART_PROXY, PARAMETERS]
17
        search_options = {:per_page => 999999}
18
        search_options['search'] = "organization=\"#{option_organization}\"" if option_organization
19
        @api.resource(:domains).call(:index, search_options)['results'].each do |domain|
20
          domain = @api.resource(:domains).call(:show, {'id' => domain['id']})
21
          raise "Domain 'id=#{domain['id']}' not found" if !domain || domain.empty?
22

  
23
          name = domain['name']
24
          organizations = option_organization ? option_organization : export_column(domain, 'organizations', 'name')
25
          locations = export_column(domain, 'locations', 'name')
26
          description = domain['fullname']
27
          capsule = foreman_smart_proxy(:id => domain['dns_id'])
28
          parameters = export_parameters(domain['parameters'])
29
          csv << [name, organizations, locations, description, capsule, parameters]
32 30
        end
33 31
      end
34 32

  
lib/hammer_cli_csv/host_collections.rb
8 8
      LIMIT = 'Limit'
9 9
      DESCRIPTION = 'Description'
10 10

  
11
      def export
12
        CSV.open(option_file || '/dev/stdout', 'wb') do |csv|
13
          csv << [NAME, ORGANIZATION, LIMIT, DESCRIPTION]
14
          if @server_status['release'] == 'Headpin'
15
            @headpin.get(:organizations).each do |organization|
16
              next if option_organization && organization['name'] != option_organization
17
              @headpin.get("organizations/#{organization['label']}/system_groups").each do |systemgroup|
18
                csv << [systemgroup['name'], organization['name'],
19
                        systemgroup['max_systems'].to_i < 0 ? 'Unlimited' : systemgroup['max_systems'],
20
                        systemgroup['description']]
21
              end
11
      def export(csv)
12
        csv << [NAME, ORGANIZATION, LIMIT, DESCRIPTION]
13
        if @server_status['release'] == 'Headpin'
14
          @headpin.get(:organizations).each do |organization|
15
            next if option_organization && organization['name'] != option_organization
16
            @headpin.get("organizations/#{organization['label']}/system_groups").each do |systemgroup|
17
              csv << [systemgroup['name'], organization['name'],
18
                      systemgroup['max_systems'].to_i < 0 ? 'Unlimited' : systemgroup['max_systems'],
19
                      systemgroup['description']]
22 20
            end
23
          else
24
            @api.resource(:organizations).call(:index, {'per_page' => 999999})['results'].each do |organization|
25
              next if option_organization && organization['name'] != option_organization
26
              @api.resource(:host_collections).call(:index, {
27
                  'organization_id' => organization['id']
28
              })['results'].each do |hostcollection|
29
                limit = hostcollection['unlimited_content_hosts'] ? 'Unlimited' : hostcollection['max_content_hosts']
30
                csv << [hostcollection['name'], organization['name'],
31
                        limit,
32
                        hostcollection['description']]
33
              end
21
          end
22
        else
23
          @api.resource(:organizations).call(:index, {'per_page' => 999999})['results'].each do |organization|
24
            next if option_organization && organization['name'] != option_organization
25
            @api.resource(:host_collections).call(:index, {
26
                'organization_id' => organization['id']
27
            })['results'].each do |hostcollection|
28
              limit = hostcollection['unlimited_content_hosts'] ? 'Unlimited' : hostcollection['max_content_hosts']
29
              csv << [hostcollection['name'], organization['name'],
30
                      limit,
31
                      hostcollection['description']]
34 32
            end
35 33
          end
36 34
        end
lib/hammer_cli_csv/host_groups.rb
22 22
      PASSWORD = 'Password'
23 23
      PUPPET_CLASSES = 'Puppet Classes'
24 24

  
25
      def export
26
        CSV.open(option_file || '/dev/stdout', 'wb', {:force_quotes => true}) do |csv|
27
          csv << [NAME, PARENT, ORGANIZATIONS, LOCATIONS, SUBNET, DOMAIN, OPERATING_SYSTEM,
28
                  ENVIRONMENT, COMPUTE_PROFILE, PARTITION_TABLE, MEDIUM, ARCHITECTURE, REALM,
29
                  PUPPET_PROXY, PUPPET_CA_PROXY, CONTENT_SOURCE, PASSWORD, PUPPET_CLASSES]
30
          search_options = {:per_page => 999999}
31
          search_options['search'] = "organization=\"#{option_organization}\"" if option_organization
32
          @api.resource(:hostgroups).call(:index, search_options)['results'].each do |hostgroup|
33
            hostgroup = @api.resource(:hostgroups).call(:show, {'id' => hostgroup['id']})
34
            raise "Host Group 'id=#{hostgroup['id']}' not found" if !hostgroup || hostgroup.empty?
25
      def export(csv)
26
        csv << [NAME, PARENT, ORGANIZATIONS, LOCATIONS, SUBNET, DOMAIN, OPERATING_SYSTEM,
27
                ENVIRONMENT, COMPUTE_PROFILE, PARTITION_TABLE, MEDIUM, ARCHITECTURE, REALM,
28
                PUPPET_PROXY, PUPPET_CA_PROXY, CONTENT_SOURCE, PASSWORD, PUPPET_CLASSES]
29
        search_options = {:per_page => 999999}
30
        search_options['search'] = "organization=\"#{option_organization}\"" if option_organization
31
        @api.resource(:hostgroups).call(:index, search_options)['results'].each do |hostgroup|
32
          hostgroup = @api.resource(:hostgroups).call(:show, {'id' => hostgroup['id']})
33
          raise "Host Group 'id=#{hostgroup['id']}' not found" if !hostgroup || hostgroup.empty?
35 34

  
36
            name = hostgroup['name']
37
            organizations = export_column(hostgroup, 'organizations', 'name')
38
            locations = export_column(hostgroup, 'locations', 'name')
39
            subnet = hostgroup['subnet_name']
40
            operating_system = hostgroup['operatingsystem_name']
41
            domain = hostgroup['domain_name']
42
            puppet_environment = hostgroup['environment_name']
43
            compute_profile = hostgroup['compute_profile_name']
44
            partition_table = hostgroup['ptable_name']
45
            medium = hostgroup['medium_name']
46
            architecture = hostgroup['architecture_name']
47
            realm = hostgroup['realm_name']
48
            puppet_proxy = hostgroup['puppet_proxy_id'] ? foreman_host(:id => hostgroup['puppet_proxy_id']) : nil
49
            puppet_ca_proxy = hostgroup['puppet_ca_proxy_id'] ? foreman_host(:id => hostgroup['puppet_ca_proxy_id']) : nil
50
            content_source = hostgroup['content_source_id'] ? foreman_host(:id => hostgroup['content_source_id']) : nil
51
            parent = hostgroup['ancestry'] ? foreman_hostgroup(:id => hostgroup['ancestry']) : nil
52
            password = nil
53
            puppet_classes = export_column(hostgroup, 'puppetclasses') do |puppet_class|
54
              "#{puppet_class['module_name']}/#{puppet_class['name']}"
55
            end
35
          name = hostgroup['name']
36
          organizations = export_column(hostgroup, 'organizations', 'name')
37
          locations = export_column(hostgroup, 'locations', 'name')
38
          subnet = hostgroup['subnet_name']
39
          operating_system = hostgroup['operatingsystem_name']
40
          domain = hostgroup['domain_name']
41
          puppet_environment = hostgroup['environment_name']
42
          compute_profile = hostgroup['compute_profile_name']
43
          partition_table = hostgroup['ptable_name']
44
          medium = hostgroup['medium_name']
45
          architecture = hostgroup['architecture_name']
46
          realm = hostgroup['realm_name']
47
          puppet_proxy = hostgroup['puppet_proxy_id'] ? foreman_host(:id => hostgroup['puppet_proxy_id']) : nil
48
          puppet_ca_proxy = hostgroup['puppet_ca_proxy_id'] ? foreman_host(:id => hostgroup['puppet_ca_proxy_id']) : nil
49
          content_source = hostgroup['content_source_id'] ? foreman_host(:id => hostgroup['content_source_id']) : nil
50
          parent = hostgroup['ancestry'] ? foreman_hostgroup(:id => hostgroup['ancestry']) : nil
51
          password = nil
52
          puppet_classes = export_column(hostgroup, 'puppetclasses') do |puppet_class|
53
            "#{puppet_class['module_name']}/#{puppet_class['name']}"
54
          end
56 55

  
57
            # TODO: http://projects.theforeman.org/issues/6273
58
            # API call to get the smart class variable override values
56
          # TODO: http://projects.theforeman.org/issues/6273
57
          # API call to get the smart class variable override values
59 58

  
60
            csv << [name, parent, organizations, locations, subnet, domain, operating_system,
61
                    puppet_environment, compute_profile, partition_table, medium, architecture,
62
                    realm, puppet_proxy, puppet_ca_proxy, content_source, password, puppet_classes]
63
          end
59
          csv << [name, parent, organizations, locations, subnet, domain, operating_system,
60
                  puppet_environment, compute_profile, partition_table, medium, architecture,
61
                  realm, puppet_proxy, puppet_ca_proxy, content_source, password, puppet_classes]
64 62
        end
65 63
      end
66 64

  
lib/hammer_cli_csv/hosts.rb
22 22
      ENABLED = 'Enabled'
23 23
      MANAGED = 'Managed'
24 24

  
25
      def export
26
        CSV.open(option_file || '/dev/stdout', 'wb', {:force_quotes => true}) do |csv|
27
          csv << [NAME, ORGANIZATION, LOCATION, ENVIRONMENT, OPERATINGSYSTEM, ARCHITECTURE,
28
                  MACADDRESS, DOMAIN, PARTITIONTABLE, SUBNET, REALM, MEDIUM, HOSTGROUP,
29
                  COMPUTERESOURCE, COMPUTEPROFILE, IMAGE, ENABLED, MANAGED]
30
          search_options = {:per_page => 999999}
31
          search_options['search'] = "organization=\"#{option_organization}\"" if option_organization
32
          @api.resource(:hosts).call(:index, search_options)['results'].each do |host|
33
            host = @api.resource(:hosts).call(:show, {'id' => host['id']})
34
            raise "Host 'id=#{host['id']}' not found" if !host || host.empty?
25
      def export(csv)
26
        csv << [NAME, ORGANIZATION, LOCATION, ENVIRONMENT, OPERATINGSYSTEM, ARCHITECTURE,
27
                MACADDRESS, DOMAIN, PARTITIONTABLE, SUBNET, REALM, MEDIUM, HOSTGROUP,
28
                COMPUTERESOURCE, COMPUTEPROFILE, IMAGE, ENABLED, MANAGED]
29
        search_options = {:per_page => 999999}
30
        search_options['search'] = "organization=\"#{option_organization}\"" if option_organization
31
        @api.resource(:hosts).call(:index, search_options)['results'].each do |host|
32
          host = @api.resource(:hosts).call(:show, {'id' => host['id']})
33
          raise "Host 'id=#{host['id']}' not found" if !host || host.empty?
35 34

  
36
            name = host['name']
37
            organization = host['organization_name']
38
            location = host['location_name']
39
            environment = host['environment_name']
40
            operatingsystem = host['operatingsystem_name']
41
            architecture = host['architecture_name']
42
            mac = host['mac']
43
            domain = host['domain_name']
44
            ptable = host['ptable_name']
45
            subnet = host['subnet_name']
46
            realm = host['realm_name']
47
            medium = host['medium_name']
48
            hostgroup = host['hostgroup_name']
49
            compute_resource = host['compute_resource_name']
50
            compute_profile = host['compute_profile_name']
51
            image = host['image_name']
35
          name = host['name']
36
          organization = host['organization_name']
37
          location = host['location_name']
38
          environment = host['environment_name']
39
          operatingsystem = host['operatingsystem_name']
40
          architecture = host['architecture_name']
41
          mac = host['mac']
42
          domain = host['domain_name']
43
          ptable = host['ptable_name']
44
          subnet = host['subnet_name']
45
          realm = host['realm_name']
46
          medium = host['medium_name']
47
          hostgroup = host['hostgroup_name']
48
          compute_resource = host['compute_resource_name']
49
          compute_profile = host['compute_profile_name']
50
          image = host['image_name']
52 51

  
53
            enabled = host['enabled'] ? 'Yes' : 'No'
54
            managed = host['managed'] ? 'Yes' : 'No'
52
          enabled = host['enabled'] ? 'Yes' : 'No'
53
          managed = host['managed'] ? 'Yes' : 'No'
55 54

  
56
            csv << [name, organization, location, environment, operatingsystem, architecture,
57
                    mac, domain, ptable, subnet, realm, medium, hostgroup, compute_resource,
58
                    compute_profile, image, enabled, managed]
59
          end
55
          csv << [name, organization, location, environment, operatingsystem, architecture,
56
                  mac, domain, ptable, subnet, realm, medium, hostgroup, compute_resource,
57
                  compute_profile, image, enabled, managed]
60 58
        end
61 59
      end
62 60

  
lib/hammer_cli_csv/installation_media.rb
10 10
      OSFAMILY = 'OS Family'
11 11
      OPERATING_SYSTEMS = 'Operating Systems'
12 12

  
13
      def export
14
        CSV.open(option_file || '/dev/stdout', 'wb', {:force_quotes => true}) do |csv|
15
          csv << [NAME, ORGANIZATIONS, LOCATIONS, PATH, OSFAMILY, OPERATING_SYSTEMS]
16
          @api.resource(:media).call(:index, {:per_page => 999999})['results'].each do |medium|
17
            medium = @api.resource(:media).call(:show, :id => medium['id'])
18
            name = medium['name']
19
            organizations = export_column(medium, 'organizations', 'name')
20
            locations = export_column(medium, 'locations', 'name')
21
            count = 1
22
            path = medium['path']
23
            os_family = medium['os_family']
24
            operating_systems = export_column(medium, 'operatingsystems', 'title')
25
            csv << [name, organizations, locations, path, os_family, operating_systems]
26
          end
13
      def export(csv)
14
        csv << [NAME, ORGANIZATIONS, LOCATIONS, PATH, OSFAMILY, OPERATING_SYSTEMS]
15
        @api.resource(:media).call(:index, {:per_page => 999999})['results'].each do |medium|
16
          medium = @api.resource(:media).call(:show, :id => medium['id'])
17
          name = medium['name']
18
          organizations = export_column(medium, 'organizations', 'name')
19
          locations = export_column(medium, 'locations', 'name')
20
          count = 1
21
          path = medium['path']
22
          os_family = medium['os_family']
23
          operating_systems = export_column(medium, 'operatingsystems', 'title')
24
          csv << [name, organizations, locations, path, os_family, operating_systems]
27 25
        end
28 26
      end
29 27

  
lib/hammer_cli_csv/job_templates.rb
17 17
      INPUT_TYPE = 'Input:Type'
18 18
      INPUT_PARAMETERS = 'Input:Parameters'
19 19

  
20
      def export
21
        CSV.open(option_file || '/dev/stdout', 'wb', {:force_quotes => true}) do |csv|
22
          csv << [NAME, ORGANIZATIONS, LOCATIONS, DESCRIPTION, JOB, PROVIDER, SNIPPET, TEMPLATE,
23
                  INPUT_NAME, INPUT_DESCRIPTION, INPUT_REQUIRED, INPUT_TYPE, INPUT_PARAMETERS]
24
          @api.resource(:job_templates).call(:index, {
25
              :per_page => 999999
26
          })['results'].each do |template_id|
27
            template = @api.resource(:job_templates).call(:show, {:id => template_id['id']})
28
            next if template['locked']
29
            next unless option_organization.nil? || template['organizations'].detect { |org| org['name'] == option_organization }
30
            name = template['name']
31
            description = template['description_format']
32
            job = template['job_category']
33
            snippet = template['snippet'] ? 'Yes' : 'No'
34
            provider = template['provider_type']
35
            organizations = export_column(template, 'organizations', 'name')
36
            locations = export_column(template, 'locations', 'name')
37
            csv << [name, organizations, locations, description, job, provider, snippet, template['template']]
20
      def export(csv)
21
        csv << [NAME, ORGANIZATIONS, LOCATIONS, DESCRIPTION, JOB, PROVIDER, SNIPPET, TEMPLATE,
22
                INPUT_NAME, INPUT_DESCRIPTION, INPUT_REQUIRED, INPUT_TYPE, INPUT_PARAMETERS]
23
        @api.resource(:job_templates).call(:index, {
24
            :per_page => 999999
25
        })['results'].each do |template_id|
26
          template = @api.resource(:job_templates).call(:show, {:id => template_id['id']})
27
          next if template['locked']
28
          next unless option_organization.nil? || template['organizations'].detect { |org| org['name'] == option_organization }
29
          name = template['name']
30
          description = template['description_format']
31
          job = template['job_category']
32
          snippet = template['snippet'] ? 'Yes' : 'No'
33
          provider = template['provider_type']
34
          organizations = export_column(template, 'organizations', 'name')
35
          locations = export_column(template, 'locations', 'name')
36
          csv << [name, organizations, locations, description, job, provider, snippet, template['template']]
38 37

  
39
            template_columns = [name] + Array.new(7)
40
            @api.resource(:template_inputs).call(:index, {
41
                :template_id => template['id']
42
            })['results'].each  do|input|
43
              input_field = nil
44
              input_options = nil
45
              case input['input_type']
46
              when /user/
47
                input_name = export_column(input, 'options') do |value|
48
                  value
49
                end
50
              when /fact/
51
                input_name = input['fact_name']
52
              when /variable/
53
                input_name = input['variable_name']
54
              when /puppet_parameter/
55
                input_name = "#{input['puppet_class_name']}|#{input['puppet_parameter_name']}"
56
              else
57
                raise _("Unknown job template input type '%{type}'") % {:type => input['input_type']}
38
          template_columns = [name] + Array.new(7)
39
          @api.resource(:template_inputs).call(:index, {
40
              :template_id => template['id']
41
          })['results'].each  do|input|
42
            input_field = nil
43
            input_options = nil
44
            case input['input_type']
45
            when /user/
46
              input_name = export_column(input, 'options') do |value|
47
                value
58 48
              end
59
              required = input['required'] ? 'Yes' : 'No'
60
              csv << template_columns + [input['name'], input['description'], required, input['input_type'], input_name]
49
            when /fact/
50
              input_name = input['fact_name']
51
            when /variable/
52
              input_name = input['variable_name']
53
            when /puppet_parameter/
54
              input_name = "#{input['puppet_class_name']}|#{input['puppet_parameter_name']}"
55
            else
56
              raise _("Unknown job template input type '%{type}'") % {:type => input['input_type']}
61 57
            end
58
            required = input['required'] ? 'Yes' : 'No'
59
            csv << template_columns + [input['name'], input['description'], required, input['input_type'], input_name]
62 60
          end
63 61
        end
64 62
      end
lib/hammer_cli_csv/lifecycle_environments.rb
8 8
      PRIORENVIRONMENT = 'Prior Environment'
9 9
      DESCRIPTION = 'Description'
10 10

  
11
      def export
12
        CSV.open(option_file || '/dev/stdout', 'wb', {:force_quotes => true}) do |csv|
13
          csv << [NAME, ORGANIZATION, PRIORENVIRONMENT, DESCRIPTION]
14
          @api.resource(:organizations).call(:index, {
15
              'per_page' => 999999
16
          })['results'].each do |organization|
17
            next if option_organization && organization['name'] != option_organization
11
      def export(csv)
12
        csv << [NAME, ORGANIZATION, PRIORENVIRONMENT, DESCRIPTION]
13
        @api.resource(:organizations).call(:index, {
14
            'per_page' => 999999
15
        })['results'].each do |organization|
16
          next if option_organization && organization['name'] != option_organization
18 17

  
19
            @api.resource(:lifecycle_environments).call(:index, {
20
                'per_page' => 999999,
21
                'organization_id' => organization['id']
22
            })['results'].sort { |a, b| a['created_at'] <=> b['created_at'] }.each do |environment|
23
              if environment['name'] != 'Library'
24
                name = environment['name']
25
                prior = environment['prior']['name']
26
                description = environment['description']
27
                csv << [name, organization['name'], prior, description]
28
              end
18
          @api.resource(:lifecycle_environments).call(:index, {
19
              'per_page' => 999999,
20
              'organization_id' => organization['id']
21
          })['results'].sort { |a, b| a['created_at'] <=> b['created_at'] }.each do |environment|
22
            if environment['name'] != 'Library'
23
              name = environment['name']
24
              prior = environment['prior']['name']
25
              description = environment['description']
26
              csv << [name, organization['name'], prior, description]
29 27
            end
30 28
          end
31 29
        end
lib/hammer_cli_csv/locations.rb
6 6

  
7 7
      PARENT = 'Parent Location'
8 8

  
9
      def export
10
        CSV.open(option_file || '/dev/stdout', 'wb', {:force_quotes => true}) do |csv|
11
          csv << [NAME, PARENT]
12
          @api.resource(:locations).call(:index, {:per_page => 999999})['results'].each do |location|
13
            csv << [location['name'], '']
14
          end
9
      def export(csv)
10
        csv << [NAME, PARENT]
11
        @api.resource(:locations).call(:index, {:per_page => 999999})['results'].each do |location|
12
          csv << [location['name'], '']
15 13
        end
16 14
      end
17 15

  
lib/hammer_cli_csv/operating_systems.rb
13 13
      PROVISIONING_TEMPLATES = 'Provisioning Templates'
14 14
      PARAMETERS = 'Parameters'
15 15

  
16
      def export
17
        CSV.open(option_file || '/dev/stdout', 'wb', {:force_quotes => true}) do |csv|
18
          csv << [NAME, DESCRIPTION, FAMILY, PASSWORD_HASH, PARTITION_TABLES, ARCHITECTURES, MEDIA,
19
                  PROVISIONING_TEMPLATES, PARAMETERS]
20
          @api.resource(:operatingsystems).call(:index, {:per_page => 999999})['results'].each do |operatingsystem_id|
21
            operatingsystem = @api.resource(:operatingsystems).call(:show, {:id => operatingsystem_id['id']})
22
            name = build_os_name(operatingsystem['name'], operatingsystem['major'], operatingsystem['minor'])
23
            description = operatingsystem['description']
24
            family = operatingsystem['family']
25
            password_hash = operatingsystem['password_hash']
26
            partition_tables = export_column(operatingsystem, 'ptables', 'name')
27
            architectures = export_column(operatingsystem, 'architectures', 'name')
28
            media = export_column(operatingsystem, 'media', 'name')
29
            partition_tables = export_column(operatingsystem, 'ptables', 'name')
30
            parameters = export_column(operatingsystem, 'parameters') do |parameter|
31
              "#{parameter['name']}|#{parameter['value']}"
32
            end
33
            csv << [name, description, family, password_hash, partition_tables, architectures,
34
                    media, partition_tables, parameters]
16
      def export(csv)
17
        csv << [NAME, DESCRIPTION, FAMILY, PASSWORD_HASH, PARTITION_TABLES, ARCHITECTURES, MEDIA,
18
                PROVISIONING_TEMPLATES, PARAMETERS]
19
        @api.resource(:operatingsystems).call(:index, {:per_page => 999999})['results'].each do |operatingsystem_id|
20
          operatingsystem = @api.resource(:operatingsystems).call(:show, {:id => operatingsystem_id['id']})
21
          name = build_os_name(operatingsystem['name'], operatingsystem['major'], operatingsystem['minor'])
22
          description = operatingsystem['description']
23
          family = operatingsystem['family']
24
          password_hash = operatingsystem['password_hash']
25
          partition_tables = export_column(operatingsystem, 'ptables', 'name')
26
          architectures = export_column(operatingsystem, 'architectures', 'name')
27
          media = export_column(operatingsystem, 'media', 'name')
28
          partition_tables = export_column(operatingsystem, 'ptables', 'name')
29
          parameters = export_column(operatingsystem, 'parameters') do |parameter|
30
            "#{parameter['name']}|#{parameter['value']}"
35 31
          end
32
          csv << [name, description, family, password_hash, partition_tables, architectures,
33
                  media, partition_tables, parameters]
36 34
        end
37 35
      end
38 36

  
lib/hammer_cli_csv/organizations.rb
7 7
      LABEL = 'Label'
8 8
      DESCRIPTION = 'Description'
9 9

  
10
      def export
11
        CSV.open(option_file || '/dev/stdout', 'wb', {:force_quotes => true}) do |csv|
12
          csv << [NAME, LABEL, DESCRIPTION]
10
      def export(csv)
11
        csv << [NAME, LABEL, DESCRIPTION]
13 12

  
14
          if @server_status['release'] == 'Headpin'
15
            @headpin.get(:organizations).each do |organization|
16
              next if option_organization && organization['name'] != option_organization
17
              csv << [organization['name'], organization['label'], organization['description']]
18
            end
19
          else
20
            @api.resource(:organizations).call(:index, {:per_page => 999999})['results'].each do |organization|
21
              next if option_organization && organization['name'] != option_organization
22
              csv << [organization['name'], organization['label'], organization['description']]
23
            end
13
        if @server_status['release'] == 'Headpin'
14
          @headpin.get(:organizations).each do |organization|
15
            next if option_organization && organization['name'] != option_organization
16
            csv << [organization['name'], organization['label'], organization['description']]
17
          end
18
        else
19
          @api.resource(:organizations).call(:index, {:per_page => 999999})['results'].each do |organization|
20
            next if option_organization && organization['name'] != option_organization
21
            csv << [organization['name'], organization['label'], organization['description']]
24 22
          end
25 23
        end
26 24
      end
lib/hammer_cli_csv/partition_tables.rb
10 10
      OPERATINGSYSTEMS = 'Operating Systems'
11 11
      LAYOUT = 'Layout'
12 12

  
13
      def export
13
      def export(csv)
14 14
        # TODO: partition-tables do not return their organizations or locations
15 15
        # http://projects.theforeman.org/issues/11175
16 16
        organizations_map = {}
......
28 28
          end
29 29
        end
30 30

  
31
        CSV.open(option_file || '/dev/stdout', 'wb', {:force_quotes => true}) do |csv|
32
          csv << [NAME, ORGANIZATIONS, LOCATIONS, OSFAMILY, OPERATINGSYSTEMS, LAYOUT]
33
          @api.resource(:ptables).call(:index, {:per_page => 999999})['results'].each do |ptable|
34
            ptable = @api.resource(:ptables).call(:show, {'id' => ptable['id']})
35
            name = ptable['name']
36
            osfamily = ptable['os_family']
37
            layout = ptable['layout']
38
            operatingsystems = export_column(ptable, 'operatingsystems', 'title')
39

  
40
            organizations = CSV.generate do |column|
41
              column << organizations_map[name] if organizations_map[name]
42
            end
43
            organizations.delete!("\n")
44
            locations = CSV.generate do |column|
45
              column << locations_map[name] if locations_map[name]
46
            end
47
            locations.delete!("\n")
31
        csv << [NAME, ORGANIZATIONS, LOCATIONS, OSFAMILY, OPERATINGSYSTEMS, LAYOUT]
32
        @api.resource(:ptables).call(:index, {:per_page => 999999})['results'].each do |ptable|
33
          ptable = @api.resource(:ptables).call(:show, {'id' => ptable['id']})
34
          name = ptable['name']
35
          osfamily = ptable['os_family']
36
          layout = ptable['layout']
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff