Project

General

Profile

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

hammer-cli-csv / lib / hammer_cli_csv / content_view_filters.rb @ c4dbc7a3

1
# NOTE:
2
#   rpm -qa --queryformat "%{NAME}|=|%{VERSION}-%{RELEASE},"
3

    
4
module HammerCLICsv
5
  class CsvCommand
6
    class ContentViewFiltersCommand < BaseCommand
7
      command_name 'content-view-filters'
8
      desc         'import or export content-view-filters'
9

    
10
      CONTENTVIEW = 'Content View'
11
      ORGANIZATION = 'Organization'
12
      DESCRIPTION = 'Description'
13
      TYPE = 'Type'
14
      REPOSITORIES = 'Repositories'
15
      RULES = 'Rules'
16

    
17
      def export
18
        CSV.open(option_file || '/dev/stdout', 'wb', {:force_quotes => false}) do |csv|
19
          csv << [NAME, COUNT, 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, 1, contentview['name'], organization['name'], filter_type, filter['description'],
50
                        repositories, rules]
51
              end
52
            end
53
          end
54
        end
55
      end
56

    
57
      def import
58
        @existing_filters = {}
59

    
60
        thread_import do |line|
61
          create_filters_from_csv(line)
62
        end
63
      end
64

    
65
      # rubocop:disable CyclomaticComplexity
66
      def create_filters_from_csv(line)
67
        return if option_organization && line[ORGANIZATION] != option_organization
68

    
69
        @existing_filters[line[ORGANIZATION]] ||= {}
70
        if !@existing_filters[line[ORGANIZATION]][line[CONTENTVIEW]]
71
          @existing_filters[line[ORGANIZATION]][line[CONTENTVIEW]] ||= {}
72
          @api.resource(:content_view_filters).call(:index, {
73
              'per_page' => 999999,
74
              'content_view_id' => katello_contentview(line[ORGANIZATION], :name => line[CONTENTVIEW])
75
          })['results'].each do |filter|
76
            @existing_filters[line[ORGANIZATION]][line[CONTENTVIEW]][filter['name']] = filter['id'] if filter
77
          end
78
        end
79

    
80
        repository_ids = collect_column(line[REPOSITORIES]) do |repository|
81
          katello_repository(line[ORGANIZATION], :name => repository)
82
        end
83

    
84
        line[COUNT].to_i.times do |number|
85
          filter_name = namify(line[NAME], number)
86

    
87
          filter_id = @existing_filters[line[ORGANIZATION]][line[CONTENTVIEW]][filter_name]
88
          filter_type = import_filter_type(line[TYPE])
89
          if !filter_id
90
            print "Creating filter '#{filter_name}' for content view filter '#{line[CONTENTVIEW]}'..." if option_verbose?
91
            filter_id = @api.resource(:content_view_filters).call(:create, {
92
                'content_view_id' => katello_contentview(line[ORGANIZATION], :name => line[CONTENTVIEW]),
93
                'name' => filter_name,
94
                'description' => line[DESCRIPTION],
95
                'type' => filter_type,
96
                'inclusion' => filter_inclusion?(line[TYPE]),
97
                'repository_ids' => repository_ids
98
            })['id']
99
            @existing_filters[line[ORGANIZATION]][filter_name] = filter_id
100
          else
101
            print "Updating filter '#{filter_name}' for content view filter '#{line[CONTENTVIEW]}'..." if option_verbose?
102
            @api.resource(:content_view_filters).call(:update, {
103
                'id' => filter_id,
104
                'description' => line[DESCRIPTION],
105
                'type' => filter_type,
106
                'inclusion' => filter_inclusion?(line[TYPE]),
107
                'repository_ids' => repository_ids
108
            })
109
          end
110

    
111
          existing_rules = {}
112
          @api.resource(:content_view_filter_rules).call(:index, {
113
              'per_page' => 999999,
114
              'content_view_filter_id' => filter_id
115
          })['results'].each do |rule|
116
            existing_rules[rule['name']] = rule
117
          end
118

    
119
          collect_column(line[RULES]) do |rule|
120
            name, type, version = rule.split('|')
121
            params = {
122
              'content_view_filter_id' => filter_id,
123
              'name' => name
124
            }
125
            if type == 'all'
126
              # empty
127
            elsif type == '='
128
              params['version'] = version
129
            elsif type == '<'
130
              params['max_version'] = version
131
            elsif type == '>'
132
              params['min_version'] = version
133
            elsif type == '-'
134
              min_version, max_version = version.split(',')
135
              params['min_version'] = min_version
136
              params['max_version'] = max_version
137
            elsif filter_type == 'package_group'
138
              params['uuid'] = name # TODO: this is not right
139
            else
140
              raise "Unknown type '#{type}' from '#{line[RULES]}'"
141
            end
142

    
143
            rule = existing_rules[name]
144
            if !rule
145
              print "." if option_verbose?
146
              rule = @api.resource(:content_view_filter_rules).call(:create, params)
147
              existing_rules[rule['name']] = rule
148
            else
149
              print "." if option_verbose?
150
              params['id'] = rule['id']
151
              @api.resource(:content_view_filter_rules).call(:update, params)
152
            end
153
          end
154

    
155
          puts 'done' if option_verbose?
156
        end
157

    
158
      rescue RuntimeError => e
159
        raise "#{e}\n       #{line}"
160
      end
161

    
162
      private
163

    
164
      def import_filter_type(type)
165
        case type.split[1..-1].join(' ')
166
        when /packages/i
167
          'rpm'
168
        when /package groups/i
169
          'package_group'
170
        else
171
          'unknown'
172
        end
173
      end
174

    
175
      def export_filter_type(type)
176
        case type.split[1]
177
        when /rpm/i
178
          'Packages'
179
        when /package_group/i
180
          'Package Groups'
181
        else
182
          'unknown'
183
        end
184
      end
185

    
186
      def filter_inclusion?(type)
187
        if type.split[0] == 'Include'
188
          true
189
        else
190
          false
191
        end
192
      end
193

    
194
      def export_rpm_rules(filter)
195
        rules = CSV.generate do |column|
196
          column << filter['rules'].collect do |rule|
197
            if rule['version']
198
              "#{rule['name']}|=|#{rule['version']}"
199
            elsif rule['min_version'] && rule['max_version']
200
              "#{rule['name']}|-|#{rule['min_version']},#{rule['max_version']}"
201
            elsif rule['min_version']
202
              "#{rule['name']}|>|#{rule['min_version']}"
203
            elsif rule['max_version']
204
              "#{rule['name']}|<|#{rule['max_version']}"
205
            else
206
              "#{rule['name']}|all"
207
            end
208
          end
209
        end
210
        rules.delete!("\n")
211
      end
212

    
213
      def export_erratum_rules(filter)
214
        rules = CSV.generate do |column|
215
          rule = filter['rules'][0]
216
          conditions = []
217
          conditions << "start = #{DateTime.parse(rule['start_date']).strftime('%F')}" if rule['start_date']
218
          conditions << "end = #{DateTime.parse(rule['end_date']).strftime('%F')}" if rule['end_date']
219
          conditions << "types = #{rule['types'].join(',')}" if rule['types']
220
          conditions << "errata = #{rule['errata_id']}" if rule['errata_id']
221
          column << conditions
222
        end
223
        rules.delete!("\n")
224
      end
225

    
226
      def export_package_group_rules(filter)
227
        rules = CSV.generate do |column|
228
          column << filter['rules'].collect do |rule|
229
            rule['name']
230
          end
231
        end
232
        rules.delete!("\n")
233
      end
234
    end
235
  end
236
end