Project

General

Profile

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

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

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(csv)
18
        csv << [NAME, CONTENTVIEW, ORGANIZATION, TYPE, DESCRIPTION, REPOSITORIES, RULES]
19
        @api.resource(:organizations).call(:index, {
20
            :per_page => 999999
21
        })['results'].each do |organization|
22
          next if option_organization && organization['name'] != option_organization
23

    
24
          @api.resource(:content_views).call(:index, {
25
              'per_page' => 999999,
26
              'organization_id' => organization['id'],
27
              'nondefault' => true
28
          })['results'].each do |contentview|
29
            @api.resource(:content_view_filters).call(:index, {
30
                'content_view_id' => contentview['id']
31
            })['results'].collect do |filter|
32
              filter_type = "#{filter['inclusion'] == true ? 'Include' : 'Exclude'} #{export_filter_type(filter['type'])}"
33

    
34
              rules = nil
35
              case filter['type']
36
              when /rpm/
37
                rules = export_rpm_rules(filter)
38
              when /erratum/
39
                rules = export_erratum_rules(filter)
40
              when /package_group/
41
                rules = export_package_group_rules(filter)
42
              else
43
                raise "Unknown filter rule type '#{filter['type']}'"
44
              end
45

    
46
              name = filter['name']
47
              repositories = export_column(filter, 'repositories', 'name')
48
              csv << [name, contentview['name'], organization['name'], filter_type, filter['description'],
49
                      repositories, rules]
50
            end
51
          end
52
        end
53
      end
54

    
55
      def import
56
        @existing_filters = {}
57

    
58
        thread_import do |line|
59
          create_filters_from_csv(line)
60
        end
61
      end
62

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

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

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

    
82
        count(line[COUNT]).times do |number|
83
          filter_name = namify(line[NAME], number)
84

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

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

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

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

    
153
          puts 'done' if option_verbose?
154
        end
155

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

    
160
      private
161

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

    
173
      def export_filter_type(type)
174
        case type
175
        when /rpm/i
176
          'Packages'
177
        when /package_group/i
178
          'Package Groups'
179
        else
180
          'unknown'
181
        end
182
      end
183

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

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

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

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