Project

General

Profile

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

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

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
          # drop 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
            @api.resource(:content_view_filter_rules).call(:destroy, {
115
                'content_view_filter_id' => filter_id,
116
                'id' =>  rule['id']
117
            })
118
          end
119

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

    
144
            print "." if option_verbose?
145
            @api.resource(:content_view_filter_rules).call(:create, params)
146
          end
147

    
148
          puts 'done' if option_verbose?
149
        end
150

    
151
      end
152

    
153
      private
154

    
155
      def import_filter_type(type)
156
        case type.split[1..-1].join(' ')
157
        when /packages/i
158
          'rpm'
159
        when /package groups/i
160
          'package_group'
161
        else
162
          'unknown'
163
        end
164
      end
165

    
166
      def export_filter_type(type)
167
        case type
168
        when /rpm/i
169
          'Packages'
170
        when /package_group/i
171
          'Package Groups'
172
        else
173
          'unknown'
174
        end
175
      end
176

    
177
      def filter_inclusion?(type)
178
        if type.split[0] == 'Include'
179
          true
180
        else
181
          false
182
        end
183
      end
184

    
185
      def export_rpm_rules(filter)
186
        rules = CSV.generate do |column|
187
          column << filter['rules'].collect do |rule|
188
            if rule['version']
189
              "#{rule['name']}|=|#{rule['version']}"
190
            elsif rule['min_version'] && rule['max_version']
191
              "#{rule['name']}|-|#{rule['min_version']},#{rule['max_version']}"
192
            elsif rule['min_version']
193
              "#{rule['name']}|>|#{rule['min_version']}"
194
            elsif rule['max_version']
195
              "#{rule['name']}|<|#{rule['max_version']}"
196
            else
197
              "#{rule['name']}|all"
198
            end
199
          end
200
        end
201
        rules.delete!("\n")
202
      end
203

    
204
      def export_erratum_rules(filter)
205
        rules = CSV.generate do |column|
206
          rule = filter['rules'][0]
207
          conditions = []
208
          conditions << "start = #{DateTime.parse(rule['start_date']).strftime('%F')}" if rule['start_date']
209
          conditions << "end = #{DateTime.parse(rule['end_date']).strftime('%F')}" if rule['end_date']
210
          conditions << "types = #{rule['types'].join(',')}" if rule['types']
211
          conditions << "errata = #{rule['errata_id']}" if rule['errata_id']
212
          column << conditions
213
        end
214
        rules.delete!("\n")
215
      end
216

    
217
      def export_package_group_rules(filter)
218
        rules = CSV.generate do |column|
219
          column << filter['rules'].collect do |rule|
220
            rule['name']
221
          end
222
        end
223
        rules.delete!("\n")
224
      end
225
    end
226
  end
227
end