Project

General

Profile

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

hammer-cli-csv / lib / hammer_cli_csv / products.rb @ 561a8ac9

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
module HammerCLICsv
13
  class CsvCommand
14
    class ProductsCommand < BaseCommand
15
      command_name 'products'
16
      desc         'import or export products'
17

    
18
      LABEL = 'Label'
19
      ORGANIZATION = 'Organization'
20
      REPOSITORY = 'Repository'
21
      REPOSITORY_TYPE = 'Repository Type'
22
      REPOSITORY_URL = 'Repository Url'
23
      DESCRIPTION = 'Description'
24

    
25
      def export
26
        CSV.open(option_csv_file || '/dev/stdout', 'wb', {:force_quotes => false}) do |csv|
27
          csv << [NAME, COUNT, LABEL, ORGANIZATION, REPOSITORY, REPOSITORY_TYPE, REPOSITORY_URL]
28
          @api.resource(:organizations)\
29
            .call(:index, {
30
                    :per_page => 999999
31
                  })['results'].each do |organization|
32
            @api.resource(:products)\
33
              .call(:index, {
34
                      'per_page' => 999999,
35
                      'enabled' => true,
36
                      'organization_id' => foreman_organization(:name => organization['name'])
37
                    })['results'].each do |product|
38
              product['repositories'].each do |repository|
39
                repository_type = repository['product_type'] == 'custom' ? 'Custom' : 'Red Hat'
40
                repository_type += " #{repository['content_type'].capitalize}"
41
                csv << [product['name'], 1, product['label'], organization['name'],
42
                        repository['name'], repository_type, repository['url']]
43
              end
44
            end
45
          end
46
        end
47
      end
48

    
49
      def import
50
        @existing_products = {}
51
        @existing_repositories = {}
52

    
53
        thread_import do |line|
54
          create_products_from_csv(line)
55
        end
56
      end
57

    
58
      def create_products_from_csv(line)
59
        if !@existing_products[line[ORGANIZATION]]
60
          @existing_products[line[ORGANIZATION]] = {}
61
          @api.resource(:products)\
62
            .call(:index, {
63
                    'per_page' => 999999,
64
                    'organization_id' => foreman_organization(:name => line[ORGANIZATION]),
65
                    'enabled' => true
66
                  })['results'].each do |product|
67
            @existing_products[line[ORGANIZATION]][product['name']] = product['id']
68

    
69
            @api.resource(:repositories)\
70
              .call(:index, {
71
                      'page_size' => 999999, 'paged' => true,
72
                      'organization_id' => foreman_organization(:name => line[ORGANIZATION]),
73
                      'product_id' => product['id'],
74
                      'enabled' => true,
75
                      'library' => true
76
                    })['results'].each do |repository|
77
              @existing_repositories[line[ORGANIZATION] + product['name']] ||= {}
78
              @existing_repositories[line[ORGANIZATION] + product['name']][repository['label']] = repository['id']
79
            end
80
          end
81
        end
82

    
83
        line[COUNT].to_i.times do |number|
84
          name = namify(line[NAME], number)
85
          product_id = @existing_products[line[ORGANIZATION]][name]
86
          if product_id.nil?
87
            print "Creating product '#{name}'..." if option_verbose?
88
            if line[REPOSITORY_TYPE] =~ /Red Hat/
89
              raise "Red Hat product '#{name}' does not exist in '#{line[ORGANIZATION]}'"
90
            end
91

    
92
            product_id = @api.resource(:products)\
93
              .call(:create, {
94
                      'organization_id' => foreman_organization(:name => line[ORGANIZATION]),
95
                      'name' => name
96
                    })['id']
97
            @existing_products[line[ORGANIZATION]][name] = product_id
98
          else
99
            # Nothing to update for products
100
            print "Updating product '#{name}'..." if option_verbose?
101
          end
102
          @existing_repositories[line[ORGANIZATION] + name] = {}
103
          print "done\n" if option_verbose?
104

    
105
          repository_name = namify(line[REPOSITORY], number)
106

    
107
          if !@existing_repositories[line[ORGANIZATION] + name][repository_name]
108
            @api.resource(:repositories)\
109
              .call(:index, {
110
                      'organization_id' => foreman_organization(:name => line[ORGANIZATION]),
111
                      'library' => true,
112
                      'all' => false,
113
                      'product_id' => product_id
114
                    })['results'].each do |repository|
115
              @existing_repositories[line[ORGANIZATION] + name][repository['name']] = repository
116
            end
117
          end
118

    
119
          repository = @existing_repositories[line[ORGANIZATION] + name][repository_name]
120
          if !repository
121
            raise "Red Hat product '#{name}' does not have repository '#{repository_name}'" if line[REPOSITORY_TYPE] =~ /Red Hat/
122

    
123
            print "Creating repository '#{repository_name}' in product '#{name}'..." if option_verbose?
124
            repository = @api.resource(:repositories)\
125
              .call(:create, {
126
                      'organization_id' => foreman_organization(:name => line[ORGANIZATION]),
127
                      'name' => repository_name,
128
                      'label' => labelize(repository_name),
129
                      'product_id' => product_id,
130
                      'url' => line[REPOSITORY_URL],
131
                      'content_type' => content_type(line[REPOSITORY_TYPE])
132
                    })
133
            @existing_repositories[line[ORGANIZATION] + name][line[LABEL]] = repository
134
            puts 'done' if option_verbose?
135
          end
136

    
137
          print "Sync'ing repository '#{repository_name}' in product '#{name}'..." if option_verbose?
138
          if repository['sync_state'] == 'finished'
139
            puts 'already done' if option_verbose?
140
          else
141
            if line[REPOSITORY_TYPE] =~ /Red Hat/
142
              print 'skipping Red Hat repo sync... so slow!... '
143
            else
144
              sync_repository(line, repository)
145
            end
146
            print "done\n" if option_verbose?
147
          end
148
        end
149

    
150
      rescue RuntimeError => e
151
        raise "#{e}\n       #{line}"
152
      end
153

    
154
      private
155

    
156
      def content_type(repository_type)
157
        case repository_type
158
        when /yum/i
159
          'yum'
160
        when /puppet/i
161
          'puppet'
162
        else
163
          raise "Unrecognized repository type '#{repository_type}'"
164
        end
165
      end
166

    
167
      def sync_repository(line, repository)
168
        # TODO: --server needs to come from config/settings
169
        args = %W{ repository synchronize
170
                   --id #{ repository['id'] }
171
                   --organization-id #{ foreman_organization(:name => line[ORGANIZATION]) } }
172
        hammer.run(args)
173

    
174
      rescue RuntimeError => e
175
        raise "#{e}\n       #{line}"
176
      end
177
    end
178
  end
179
end