Project

General

Profile

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

hammer-cli-csv / lib / hammer_cli_csv / puppet_reports.rb @ f8ecc788

1
# Copyright 2013-2014 Red Hat, Inc.
2
#
3
# This software is licensed to you under the GNU General Public
4
# License as published by the Free Software Foundation; either version
5
# 2 of the License (GPLv2) or (at your option) any later version.
6
# There is NO WARRANTY for this software, express or implied,
7
# including the implied warranties of MERCHANTABILITY,
8
# NON-INFRINGEMENT, or FITNESS FOR A PARTICULAR PURPOSE. You should
9
# have received a copy of GPLv2 along with this software; if not, see
10
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
11

    
12
#
13
# -= Systems CSV =-
14
#
15
# Columns
16
#   Name
17
#     - System name
18
#     - May contain '%d' which will be replaced with current iteration number of Count
19
#     - eg. "os%d" -> "os1"
20
#   Count
21
#     - Number of times to iterate on this line of the CSV file
22
#   MAC Address
23
#     - MAC address
24
#     - May contain '%d' which will be replaced with current iteration number of Count
25
#     - eg. "FF:FF:FF:FF:FF:%02x" -> "FF:FF:FF:FF:FF:0A"
26
#     - Warning: be sure to keep count below 255 or MAC hex will exceed limit
27
#
28

    
29
require 'hammer_cli'
30
require 'json'
31
require 'csv'
32
require 'uri'
33

    
34
module HammerCLICsv
35
  class PuppetReportsCommand < BaseCommand
36

    
37
    ORGANIZATION = 'Organization'
38
    ENVIRONMENT = 'Environment'
39
    CONTENTVIEW = 'Content View'
40
    SYSTEMGROUPS = 'System Groups'
41
    VIRTUAL = 'Virtual'
42
    HOST = 'Host'
43
    OPERATINGSYSTEM = 'OS'
44
    ARCHITECTURE = 'Arch'
45
    SOCKETS = 'Sockets'
46
    RAM = 'RAM'
47
    CORES = 'Cores'
48
    SLA = 'SLA'
49
    PRODUCTS = 'Products'
50
    SUBSCRIPTIONS = 'Subscriptions'
51

    
52
    def export
53
      CSV.open(option_csv_file || '/dev/stdout', 'wb', {:force_quotes => false}) do |csv|
54
        csv << [NAME, COUNT, ORGANIZATION, ENVIRONMENT, CONTENTVIEW, SYSTEMGROUPS, VIRTUAL, HOST,
55
               OPERATINGSYSTEM, ARCHITECTURE, SOCKETS, RAM, CORES, SLA, PRODUCTS, SUBSCRIPTIONS]
56
        @api.resource(:organizations).call(:index, {:per_page => 999999})['results'].each do |organization|
57
          @api.resource(:systems).call(:index, {
58
                                'per_page' => 999999,
59
                                'organization_id' => organization['label']
60
                               })['results'].each do |system|
61
            system = @api.resource(:systems).call(:show, {
62
                                          'id' => system['uuid'],
63
                                          'fields' => 'full'
64
                                        })
65

    
66
            name = system['name']
67
            count = 1
68
            organization_label = organization['label']
69
            environment = system['environment']['label']
70
            contentview = system['content_view']['name']
71
            systemgroups = CSV.generate do |column|
72
              column << system['systemGroups'].collect do |systemgroup|
73
                systemgroup['name']
74
              end
75
            end.delete!("\n")
76
            virtual = system['facts']['virt.is_guest'] == 'true' ? 'Yes' : 'No'
77
            host = system['host']
78
            operatingsystem = "#{system['facts']['distribution.name']} " if system['facts']['distribution.name']
79
            operatingsystem += system['facts']['distribution.version'] if system['facts']['distribution.version']
80
            architecture = system['facts']['uname.machine']
81
            sockets = system['facts']['cpu.cpu_socket(s)']
82
            ram = system['facts']['memory.memtotal']
83
            cores = system['facts']['cpu.core(s)_per_socket']
84
            sla = ""
85
            products = CSV.generate do |column|
86
              column << system['installedProducts'].collect do |product|
87
                "#{product['productId']}|#{product['productName']}"
88
              end
89
            end.delete!("\n")
90
            subscriptions = CSV.generate do |column|
91
              column << @api.resource(:subscriptions).call(:index, {
92
                                                    'system_id' => system['uuid']
93
                                                  })['results'].collect do |subscription|
94
                "#{subscription['product_id']}|#{subscription['product_name']}"
95
              end
96
            end.delete!("\n")
97
            csv << [name, count, organization_label, environment, contentview, systemgroups, virtual, host,
98
                    operatingsystem, architecture, sockets, ram, cores, sla, products, subscriptions]
99
          end
100
        end
101
      end
102
    end
103

    
104
    def import
105
      @existing = {}
106
      @host_guests = {}
107

    
108
      thread_import do |line|
109
        create_systems_from_csv(line)
110
      end
111

    
112
      print "Updating host and guest associations..." if option_verbose?
113
      @host_guests.each do |host_id, guest_ids|
114
        @api.resource(:systems).call(:update, {
115
                               'id' => host_id,
116
                               'guest_ids' => guest_ids
117
                             })
118
      end
119
      puts "done" if option_verbose?
120
    end
121

    
122
    def create_systems_from_csv(line)
123
      if !@existing[line[ORGANIZATION]]
124
        @existing[line[ORGANIZATION]] = {}
125
        @api.resource(:systems).call(:index, {'organization_id' => line[ORGANIZATION], 'page_size' => 999999})['results'].each do |system|
126
          @existing[line[ORGANIZATION]][system['name']] = system['uuid'] if system
127
        end
128
      end
129

    
130
      line[COUNT].to_i.times do |number|
131
        name = namify(line[NAME], number)
132

    
133
        # TODO w/ @daviddavis p-r
134
        #subscriptions(line).each do |subscription|
135
        #  katello_subscription(line[ORGANIZATION], :name => subscription[:number])
136
        #end
137

    
138
        if !@existing[line[ORGANIZATION]].include? name
139
          print "Creating system '#{name}'..." if option_verbose?
140
          system_id = @api.resource(:systems).call(:create, {
141
                                 'name' => name,
142
                                 'organization_id' => line[ORGANIZATION],
143
                                 'environment_id' => katello_environment(line[ORGANIZATION], :name => line[ENVIRONMENT]),
144
                                 'content_view_id' => katello_contentview(line[ORGANIZATION], :name => line[CONTENTVIEW]),
145
                                 'facts' => facts(line),
146
                                 'installed_products' => products(line),
147
                                 'type' => 'system'
148
                               })['uuid']
149
          @existing[line[ORGANIZATION]][name] = system_id
150
        else
151
          print "Updating system '#{name}'..." if option_verbose?
152
          puts line
153
          system_id = @api.resource(:systems).call(:update, {
154
                                 'id' => @existing[line[ORGANIZATION]][name],
155
                                 'name' => name,
156
                                 'environment_id' => katello_environment(line[ORGANIZATION], :name => line[ENVIRONMENT]),
157
                                 'content_view_id' => katello_contentview(line[ORGANIZATION], :name => line[CONTENTVIEW]),
158
                                 'facts' => facts(line),
159
                                 'installed_products' => products(line)
160
                               })['uuid']
161
        end
162

    
163
        if line[VIRTUAL] == 'Yes' && line[HOST]
164
          raise "Host system '#{line[HOST]}' not found" if !@existing[line[ORGANIZATION]][line[HOST]]
165
          @host_guests[@existing[line[ORGANIZATION]][line[HOST]]] ||= []
166
          @host_guests[@existing[line[ORGANIZATION]][line[HOST]]] << system_id
167
        end
168

    
169
        set_system_groups(system_id, line)
170

    
171
        puts "done" if option_verbose?
172
      end
173
    rescue RuntimeError => e
174
      raise "#{e}\n       #{line}"
175
    end
176

    
177
    private
178

    
179
    def facts(line)
180
      facts = {}
181
      facts['cpu.core(s)_per_socket'] = line[CORES]
182
      facts['cpu.cpu_socket(s)'] = line[SOCKETS]
183
      facts['memory.memtotal'] = line[RAM]
184
      facts['uname.machine'] = line[ARCHITECTURE]
185
      if line[OPERATINGSYSTEM].index(' ')
186
        (facts['distribution.name'], facts['distribution.version']) = line[OPERATINGSYSTEM].split(' ')
187
      else
188
        (facts['distribution.name'], facts['distribution.version']) = ['RHEL', line[OPERATINGSYSTEM]]
189
      end
190
      facts['virt.is_guest'] = line[VIRTUAL] == 'Yes' ? true : false
191
      facts
192
    end
193

    
194
    def set_system_groups(system_id, line)
195
      CSV.parse_line(line[SYSTEMGROUPS]).each do |systemgroup_name|
196
        @api.resource(:systemgroups).call(:add_systems, {
197
                                         'id' => katello_systemgroup(line[ORGANIZATION], :name => systemgroup_name),
198
                                         'system_ids' => [system_id]
199
                                       })
200
      end
201
    end
202

    
203
    def products(line)
204
      products = CSV.parse_line(line[PRODUCTS]).collect do |product_details|
205
        product = {}
206
        # TODO: these get passed straight through to candlepin; probably would be better to process in server
207
        #       to allow underscore product_id here
208
        (product['productId'], product['productName']) = product_details.split('|')
209
        product
210
      end
211
      products
212
    end
213

    
214
    def subscriptions(line)
215
      subscriptions = CSV.parse_line(line[SUBSCRIPTIONS]).collect do |subscription_details|
216
        subscription = {}
217
        (subscription[:number], subscription[:name]) = subscription_details.split('|')
218
        subscription
219
      end
220
      subscriptions
221
    end
222

    
223
  end
224

    
225
  HammerCLICsv::CsvCommand.subcommand("puppet-reports",
226
                                      "import or export puppet reports",
227
                                      HammerCLICsv::PuppetReportsCommand)
228
end