Project

General

Profile

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

hammer-cli-csv / lib / hammer_cli_csv / systems.rb @ 7b00acc6

1 587327f4 Tom McKay
# Copyright 2013-2014 Red Hat, Inc.
2 a1aa846b Tom McKay
#
3 587327f4 Tom McKay
# 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 a1aa846b Tom McKay
#
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 SystemsCommand < BaseCommand
36
    ORGANIZATION = 'Organization'
37
    ENVIRONMENT = 'Environment'
38
    CONTENTVIEW = 'Content View'
39 c1357ce1 Tom McKay
    SYSTEMGROUPS = 'System Groups'
40 5880960b Tom McKay
    VIRTUAL = 'Virtual'
41
    HOST = 'Host'
42
    OPERATINGSYSTEM = 'OS'
43
    ARCHITECTURE = 'Arch'
44
    SOCKETS = 'Sockets'
45
    RAM = 'RAM'
46
    CORES = 'Cores'
47
    SLA = 'SLA'
48
    PRODUCTS = 'Products'
49
    SUBSCRIPTIONS = 'Subscriptions'
50 a1aa846b Tom McKay
51
    def export
52 c1357ce1 Tom McKay
      CSV.open(option_csv_file || '/dev/stdout', 'wb', {:force_quotes => false}) do |csv|
53
        csv << [NAME, COUNT, ORGANIZATION, ENVIRONMENT, CONTENTVIEW, SYSTEMGROUPS, VIRTUAL, HOST,
54 7b00acc6 Tom McKay
                OPERATINGSYSTEM, ARCHITECTURE, SOCKETS, RAM, CORES, SLA, PRODUCTS, SUBSCRIPTIONS]
55 587327f4 Tom McKay
        @api.resource(:organizations).call(:index, {:per_page => 999999})['results'].each do |organization|
56
          @api.resource(:systems).call(:index, {
57 c1357ce1 Tom McKay
                                'per_page' => 999999,
58 8e5eda06 Tom McKay
                                'organization_id' => katello_organization(:name => organization['name'])
59 587327f4 Tom McKay
                               })['results'].each do |system|
60
            system = @api.resource(:systems).call(:show, {
61 c1357ce1 Tom McKay
                                          'id' => system['uuid'],
62
                                          'fields' => 'full'
63 587327f4 Tom McKay
                                        })
64 c1357ce1 Tom McKay
65
            name = system['name']
66
            count = 1
67 8e5eda06 Tom McKay
            organization_name = organization['name']
68 c1357ce1 Tom McKay
            environment = system['environment']['label']
69
            contentview = system['content_view']['name']
70
            systemgroups = CSV.generate do |column|
71
              column << system['systemGroups'].collect do |systemgroup|
72
                systemgroup['name']
73
              end
74 7b00acc6 Tom McKay
            end
75
            systemgroups.delete!("\n")
76 c1357ce1 Tom McKay
            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 7b00acc6 Tom McKay
            sla = ''
85 c1357ce1 Tom McKay
            products = CSV.generate do |column|
86
              column << system['installedProducts'].collect do |product|
87
                "#{product['productId']}|#{product['productName']}"
88
              end
89 7b00acc6 Tom McKay
            end
90
            products.delete!("\n")
91 c1357ce1 Tom McKay
            subscriptions = CSV.generate do |column|
92 587327f4 Tom McKay
              column << @api.resource(:subscriptions).call(:index, {
93 c1357ce1 Tom McKay
                                                    'system_id' => system['uuid']
94 587327f4 Tom McKay
                                                  })['results'].collect do |subscription|
95 c1357ce1 Tom McKay
                "#{subscription['product_id']}|#{subscription['product_name']}"
96
              end
97 7b00acc6 Tom McKay
            end
98
            subscriptions.delete!("\n")
99 8e5eda06 Tom McKay
            csv << [name, count, organization_name, environment, contentview, systemgroups, virtual, host,
100 c1357ce1 Tom McKay
                    operatingsystem, architecture, sockets, ram, cores, sla, products, subscriptions]
101
          end
102
        end
103
      end
104 a1aa846b Tom McKay
    end
105
106
    def import
107
      @existing = {}
108 6bc031bd Tom McKay
      @host_guests = {}
109 a1aa846b Tom McKay
110
      thread_import do |line|
111
        create_systems_from_csv(line)
112
      end
113 6bc031bd Tom McKay
114 7b00acc6 Tom McKay
      print 'Updating host and guest associations...' if option_verbose?
115 6bc031bd Tom McKay
      @host_guests.each do |host_id, guest_ids|
116 587327f4 Tom McKay
        @api.resource(:systems).call(:update, {
117 6bc031bd Tom McKay
                               'id' => host_id,
118
                               'guest_ids' => guest_ids
119
                             })
120
      end
121 7b00acc6 Tom McKay
      puts 'done' if option_verbose?
122 a1aa846b Tom McKay
    end
123
124
    def create_systems_from_csv(line)
125 9d9e4494 Tom McKay
      if !@existing[line[ORGANIZATION]]
126
        @existing[line[ORGANIZATION]] = {}
127 587327f4 Tom McKay
        @api.resource(:systems).call(:index, {
128 8e5eda06 Tom McKay
                              'organization_id' => katello_organization(:name => line[ORGANIZATION]),
129 587327f4 Tom McKay
                              'page_size' => 999999})['results'].each do |system|
130 9d9e4494 Tom McKay
          @existing[line[ORGANIZATION]][system['name']] = system['uuid'] if system
131
        end
132 a1aa846b Tom McKay
      end
133
134
      line[COUNT].to_i.times do |number|
135
        name = namify(line[NAME], number)
136 9d9e4494 Tom McKay
137 6bc031bd Tom McKay
        # TODO w/ @daviddavis p-r
138
        #subscriptions(line).each do |subscription|
139
        #  katello_subscription(line[ORGANIZATION], :name => subscription[:number])
140
        #end
141 9d9e4494 Tom McKay
142
        if !@existing[line[ORGANIZATION]].include? name
143 6bc031bd Tom McKay
          print "Creating system '#{name}'..." if option_verbose?
144 587327f4 Tom McKay
          system_id = @api.resource(:systems).call(:create, {
145 bf81b9cf Tom McKay
                                                     'name' => name,
146
                                                     'organization_id' => katello_organization(:name => line[ORGANIZATION]),
147
                                                     'environment_id' => katello_environment(line[ORGANIZATION], :name => line[ENVIRONMENT]),
148
                                                     'content_view_id' => katello_contentview(line[ORGANIZATION], :name => line[CONTENTVIEW]),
149 7b00acc6 Tom McKay
                                                     'facts' => facts(name, line),
150 bf81b9cf Tom McKay
                                                     'installed_products' => products(line),
151
                                                     'type' => 'system'
152
                                                   })['uuid']
153 6bc031bd Tom McKay
          @existing[line[ORGANIZATION]][name] = system_id
154 a1aa846b Tom McKay
        else
155 c1357ce1 Tom McKay
          print "Updating system '#{name}'..." if option_verbose?
156 587327f4 Tom McKay
          system_id = @api.resource(:systems).call(:update, {
157 bf81b9cf Tom McKay
                                                     'id' => @existing[line[ORGANIZATION]][name],
158
                                                     'system' => {
159
                                                       'name' => name,
160
                                                       'environment_id' => katello_environment(line[ORGANIZATION], :name => line[ENVIRONMENT]),
161
                                                       'content_view_id' => katello_contentview(line[ORGANIZATION], :name => line[CONTENTVIEW]),
162 7b00acc6 Tom McKay
                                                       'facts' => facts(name, line),
163 bf81b9cf Tom McKay
                                                       'installed_products' => products(line)
164
                                                     }
165
                                                   })['uuid']
166 6bc031bd Tom McKay
        end
167
168
        if line[VIRTUAL] == 'Yes' && line[HOST]
169
          raise "Host system '#{line[HOST]}' not found" if !@existing[line[ORGANIZATION]][line[HOST]]
170
          @host_guests[@existing[line[ORGANIZATION]][line[HOST]]] ||= []
171
          @host_guests[@existing[line[ORGANIZATION]][line[HOST]]] << system_id
172 a1aa846b Tom McKay
        end
173 6bc031bd Tom McKay
174
        set_system_groups(system_id, line)
175
176 7b00acc6 Tom McKay
        puts 'done' if option_verbose?
177 a1aa846b Tom McKay
      end
178
    rescue RuntimeError => e
179 6bc031bd Tom McKay
      raise "#{e}\n       #{line}"
180 a1aa846b Tom McKay
    end
181 9d9e4494 Tom McKay
182
    private
183
184 7b00acc6 Tom McKay
    def facts(name, line)
185 9d9e4494 Tom McKay
      facts = {}
186
      facts['cpu.core(s)_per_socket'] = line[CORES]
187
      facts['cpu.cpu_socket(s)'] = line[SOCKETS]
188
      facts['memory.memtotal'] = line[RAM]
189
      facts['uname.machine'] = line[ARCHITECTURE]
190
      if line[OPERATINGSYSTEM].index(' ')
191
        (facts['distribution.name'], facts['distribution.version']) = line[OPERATINGSYSTEM].split(' ')
192
      else
193
        (facts['distribution.name'], facts['distribution.version']) = ['RHEL', line[OPERATINGSYSTEM]]
194
      end
195 c1357ce1 Tom McKay
      facts['virt.is_guest'] = line[VIRTUAL] == 'Yes' ? true : false
196 7b00acc6 Tom McKay
      facts['virt.uuid'] = "#{line[ORGANIZATION]}/#{name}" if facts['virt.is_guest']
197 9d9e4494 Tom McKay
      facts
198
    end
199
200 6bc031bd Tom McKay
    def set_system_groups(system_id, line)
201
      CSV.parse_line(line[SYSTEMGROUPS]).each do |systemgroup_name|
202 bf81b9cf Tom McKay
        @api.resource(:system_groups).call(:add_systems, {
203 6bc031bd Tom McKay
                                         'id' => katello_systemgroup(line[ORGANIZATION], :name => systemgroup_name),
204
                                         'system_ids' => [system_id]
205
                                       })
206
      end
207
    end
208
209 9d9e4494 Tom McKay
    def products(line)
210 7b00acc6 Tom McKay
      return nil if !line[PRODUCTS]
211 9d9e4494 Tom McKay
      products = CSV.parse_line(line[PRODUCTS]).collect do |product_details|
212
        product = {}
213 c1357ce1 Tom McKay
        # TODO: these get passed straight through to candlepin; probably would be better to process in server
214
        #       to allow underscore product_id here
215
        (product['productId'], product['productName']) = product_details.split('|')
216 9d9e4494 Tom McKay
        product
217
      end
218
      products
219
    end
220
221
    def subscriptions(line)
222 7b00acc6 Tom McKay
      return nil if !line[SUBSCRIPTIONS]
223 9d9e4494 Tom McKay
      subscriptions = CSV.parse_line(line[SUBSCRIPTIONS]).collect do |subscription_details|
224
        subscription = {}
225
        (subscription[:number], subscription[:name]) = subscription_details.split('|')
226
        subscription
227
      end
228
      subscriptions
229
    end
230 a1aa846b Tom McKay
  end
231
232 7b00acc6 Tom McKay
  HammerCLI::MainCommand.subcommand('csv:systems', 'import/export systems', HammerCLICsv::SystemsCommand)
233 a1aa846b Tom McKay
end