Project

General

Profile

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

hammer-cli-csv / lib / hammer_cli_csv / products.rb @ a77acc4a

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

    
23
require 'hammer_cli'
24
require 'json'
25
require 'csv'
26
require 'uri'
27

    
28
module HammerCLICsv
29
  class CsvCommand
30
    class ProductsCommand < BaseCommand
31
      command_name 'products'
32
      desc         'import or export products'
33

    
34
      LABEL = 'Label'
35
      ORGANIZATION = 'Organization'
36
      REPOSITORY = 'Repository'
37
      REPOSITORY_TYPE = 'Repository Type'
38
      REPOSITORY_URL = 'Repository Url'
39
      DESCRIPTION = 'Description'
40

    
41
      def export
42
        CSV.open(option_csv_file || '/dev/stdout', 'wb', {:force_quotes => false}) do |csv|
43
          csv << [NAME, COUNT, LABEL, ORGANIZATION, REPOSITORY, REPOSITORY_TYPE, REPOSITORY_URL]
44
          @api.resource(:organizations).call(:index, {:per_page => 999999})['results'].each do |organization|
45
            @api.resource(:products).call(:index, {
46
                                            'per_page' => 999999,
47
                                            'enabled' => true,
48
                                            'organization_id' => foreman_organization(:name => organization['name'])
49
                                          })['results'].each do |product|
50
              # product = @api.resource(:products).call(:show, {
51
              #                                           'id' => product['id'],
52
              #                                           'fields' => 'full'
53
              #                                         })
54
              product['library_repositories'].each do |repository|
55
                if repository['sync_state'] != 'not_synced'
56
                  repository_type = "#{repository['product_type'] == 'custom' ? 'Custom' : 'Red Hat'} #{repository['content_type'].capitalize}"
57
                  csv << [namify(product['name'], 1), 1, product['label'], organization['name'], repository['name'],
58
                          repository_type, repository['feed']]
59
                  #puts "  HTTPS:                     #{repository['unprotected'] ? 'No' : 'Yes'}"
60
                end
61
              end
62

    
63
            end
64
          end
65
        end
66
      end
67

    
68
      def import
69
        @existing_products = {}
70
        @existing_repositories = {}
71

    
72
        thread_import do |line|
73
          create_products_from_csv(line)
74
        end
75
      end
76

    
77
      def create_products_from_csv(line)
78
        if !@existing_products[line[ORGANIZATION]]
79
          @existing_products[line[ORGANIZATION]] = {}
80
          @api.resource(:products).call(:index, {
81
                                 'organization_id' => foreman_organization(:name => line[ORGANIZATION]),
82
                                 'page_size' => 999999,
83
                                 'paged' => true
84
                               })['results'].each do |product|
85
            @existing_products[line[ORGANIZATION]][product['name']] = product['id'] if product
86

    
87
            if product
88
              @api.resource(:repositories).call(:index, {
89
                                        'organization_id' => foreman_organization(:name => line[ORGANIZATION]),
90
                                        'product_id' => product['id'],
91
                                        'enabled' => true,
92
                                        'library' => true,
93
                                        'page_size' => 999999, 'paged' => true
94
                                      })['results'].each do |repository|
95
                @existing_repositories[line[ORGANIZATION] + product['name']] ||= {}
96
                @existing_repositories[line[ORGANIZATION] + product['name']][repository['label']] = repository['id']
97
              end
98
            end
99
          end
100
        end
101

    
102
        # Only creating products, not updating
103
        line[COUNT].to_i.times do |number|
104
          name = namify(line[NAME], number)
105
          puts @existing_products
106
          product_id = @existing_products[line[ORGANIZATION]][name]
107
          if !product_id
108
            print "Creating product '#{name}'..." if option_verbose?
109
            if line[REPOSITORY_TYPE] =~ /Red Hat/
110
              raise "Red Hat product '#{name}' does not exist in '#{line[ORGANIZATION]}'"
111
            end
112

    
113
            product_id = @api.resource(:products).call(:create, {
114
                                                 'organization_id' => foreman_organization(:name => line[ORGANIZATION]),
115
                                                 'name' => name
116
                                               })['id']
117
            @existing_products[line[ORGANIZATION]][name] = product_id
118
          else
119
            # Nothing to update for products
120
            print "Updating product '#{name}'..." if option_verbose?
121
          end
122
          @existing_repositories[line[ORGANIZATION] + name] = {}
123
          print "done\n" if option_verbose?
124

    
125
          repository_name = namify(line[REPOSITORY], number)
126

    
127
          # Hash the existing repositories for the product
128
          if !@existing_repositories[line[ORGANIZATION] + name][repository_name]
129
            @api.resource(:repositories).call(:index, {
130
                                                'organization_id' => foreman_organization(:name => line[ORGANIZATION]),
131
                                                'library' => true,
132
                                                'all' => false,
133
                                                'product_id' => product_id
134
                                              })['results'].each do |repository|
135
              @existing_repositories[line[ORGANIZATION] + name][repository['name']] = repository
136
            end
137
          end
138

    
139
          if !@existing_repositories[line[ORGANIZATION] + name][repository_name]
140
            print "Creating repository '#{repository_name}' in product '#{name}'..." if option_verbose?
141
            if line[REPOSITORY_TYPE] =~ /Red Hat/
142
              # TMP
143
              puts 'TMP'
144
              @api.resource(:repositories).call(:index, {
145
                                                  'organization_id' => foreman_organization(:name => line[ORGANIZATION]),
146
                                                  'library' => true,
147
                                                  'all' => true,
148
                                                  'product_id' => product_id
149
                                                })['results'].each do |repository|
150
                puts repository if repository['name'] == repository_name
151
              end
152
              puts 'END TMP'
153
              #repository_id = redhat_create_repository(product_id, repository_name)
154

    
155
            else
156
              repository_id = @api.resource(:repositories).call(:create, {
157
                                         'organization_id' => foreman_organization(:name => line[ORGANIZATION]),
158
                                         'name' => repository_name,
159
                                         'label' => labelize(repository_name),
160
                                         'product_id' => product_id,
161
                                         'url' => line[REPOSITORY_URL],
162
                                         'content_type' => content_type(line[REPOSITORY_TYPE])
163
                                       })['id']
164
            end
165
            @existing_repositories[line[ORGANIZATION] + name][line[LABEL]] = repository_id
166

    
167
            puts 'TODO: skipping sync'
168
            # task_id = @api.resource(:repositories).call(:sync, {
169
            #                                               'organization_id' => foreman_organization(:name => line[ORGANIZATION]),
170
            #                                               'id' => repository_id
171
            #                                             })['id']
172
            # TODO: wait for sync task
173
            print "done\n" if option_verbose?
174
          end
175
        end
176

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

    
181
      private
182

    
183
      def redhat_create_repository(product_id, repository_name)
184
        @api.resource(:repository_sets).call(:index, {
185
                                               'product_id' => product_id
186
                                             })['results'].each do |repository|
187
          puts repository
188
          puts @api.resource(:repository_sets).call(:show, {
189
                                                      'product_id' => product_id,
190
                                                      'id' => repository['id']})
191
          return
192
          if repository['name'] == repository_name
193
            puts repository
194
            @api.resource(:repository_sets).call(:enable, {
195
                                                   'product_id' => product_id,
196
                                                   'repository_id' => repository['id']
197
                                                 })
198
            return
199
          end
200
          raise "Repository '#{repository_name}' does not exist"
201
        end
202
      end
203

    
204
      def content_type(repository_type)
205
        case repository_type
206
          when /yum/i
207
            'yum'
208
          when /puppet/i
209
            'puppet'
210
          else
211
          raise "Unrecognized repository type '#{repository_type}'"
212
        end
213
      end
214
    end
215
  end
216
end