ItemsFilter   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 146
rs 9.3999
c 0
b 0
f 0
wmc 33

8 Methods

Rating   Name   Duplication   Size   Complexity  
A get_timebased() 0 14 4
A closed_timerange() 0 6 1
A _apply_closed_timerange() 0 18 4
A build() 0 9 1
A filter_list() 0 3 1
A all_items() 0 3 1
F _build() 0 51 13
D apply() 0 29 8
1
# pylint: disable=no-member
2
3
from utils import xstr
4
from curator.api.filter import apply_filter
5
from easydict import EasyDict
6
import curator.api as api
7
import sys
8
import logging
9
10
logger = logging.getLogger(__name__)
11
12
13
class ItemsFilter(object):
14
    """
15
    Class implements curator indices/snapshot filtering by name.
16
    Supported opts: newer_than, older_than, suffix, prefix, regex, timestring.
17
    """
18
19
    def build(self, **opts):
20
        """
21
        Build items filter.
22
23
        :rtype: ItemsFilter
24
        """
25
        self.opts = EasyDict(opts)
26
        self.built_list = self._build()
27
        return self
28
29
    def get_timebased(self):
30
        """
31
        Get timebased specific filters.
32
33
        :rtype: tuple(newer_than, older_than)
34
        """
35
        result = {}
36
        for f in self.built_list:
37
            if f.get('method', None) in ('newer_than', 'older_than'):
38
                result[f['method']] = f
39
                if len(result) == 2:
40
                    break
41
42
        return (result.get('newer_than', None), result.get('older_than', None))
43
44
    @property
45
    def all_items(self):
46
        return self.opts.get('all_{0}'.format(self.act_on), None)
47
48
    @property
49
    def filter_list(self):
50
        return self.built_list
51
52
    @property
53
    def closed_timerange(self):
54
        """
55
        Closed time range specified, newer_than and older_than both present.
56
        """
57
        return len(filter(None, self.get_timebased())) == 2
58
59
    def apply(self, working_list, act_on):
60
        """
61
        Apply filters to a working list of indices/snapshots and
62
        return resulting list.
63
        """
64
        self.act_on = act_on
65
        result_list = self._apply_closed_timerange(working_list)
66
67
        if self.all_items:
68
            logger.info('Matching all %s. Ignoring parameters other than exclude.', self.act_on)
69
70
        # Closed time range couldn't be applied
71
        if result_list is None:
72
            result_list = working_list
73
74
        # Apply filters one by one (if any) from the list.
75
        for f in self.built_list:
76
            is_timebased = f.get('method', None) in ('newer_than', 'older_than')
77
            # Don't apply timebased filters for a closed time range.
78
            if self.closed_timerange and is_timebased:
79
                continue
80
            # When all items are seleted ignore filters other than exclude
81
            if self.all_items and 'exclude' not in f:
82
                continue
83
84
            logger.debug('Applying filter: %s', f)
85
            result_list = apply_filter(result_list, **f)
86
87
        return result_list
88
89
    def _apply_closed_timerange(self, working_list):
90
        """
91
        Apply separated filtering for a closed time range.
92
        In case filtering is not applied None is returned.
93
        """
94
        if self.closed_timerange:
95
            newer_than, older_than = self.get_timebased()
96
            if newer_than['value'] < older_than['value']:
97
                print 'ERROR: Wrong time period newer_than parameter must be > older_than.'
98
                sys.exit(1)
99
            if not self.all_items:
100
                # We don't apply time range filtering in case of all_* options.
101
                logger.debug('Applying time range filters, result will be intersection\n'
102
                             'newer_than: %s\nolder_than: %s', newer_than, older_than)
103
                newer_range = set(apply_filter(working_list, **newer_than))
104
                older_range = set(apply_filter(working_list, **older_than))
105
                result_list = list(newer_range & older_range)
106
                return result_list
107
108
    def _build(self):
109
        """
110
        Build filter accoriding to filtering parameters.
111
112
        :rtype: list
113
        """
114
        opts = self.opts
115
        filter_list = []
116
117
        # No timestring parameter, range parameters a given
118
        if not opts.timestring and any((xstr(opts.newer_than),
119
                                        xstr(opts.older_than))):
120
            print 'ERROR: Parameters newer_than/older_than require timestring to be given'
121
            sys.exit(1)
122
        # Timestring used alone without newer_than/older_than
123
        if opts.timestring is not None and not all((xstr(opts.newer_than),
124
                                                    xstr(opts.older_than))):
125
            f = api.filter.build_filter(kindOf='timestring',
126
                                        value=opts.timestring)
127
            if f:
128
                filter_list.append(f)
129
130
        # Timebase filtering
131
        timebased = zip(('newer_than', 'older_than'), (opts.newer_than,
132
                                                       opts.older_than))
133
        for opt, value in timebased:
134
            if value is None:
135
                continue
136
            f = api.filter.build_filter(kindOf=opt, value=value,
137
                                        timestring=opts.timestring,
138
                                        time_unit=opts.time_unit)
139
            if f:
140
                filter_list.append(f)
141
142
        # Add filtering based on suffix|prefix|regex
143
        patternbased = zip(('suffix', 'prefix', 'regex'),
144
                           (opts.suffix, opts.prefix, opts.regex))
145
146
        for opt, value in patternbased:
147
            if value is None:
148
                continue
149
            f = api.filter.build_filter(kindOf=opt, value=value)
150
            if f:
151
                filter_list.append(f)
152
153
        # Add exclude filter
154
        for pattern in opts.exclude or []:
155
            f = {'pattern': pattern, 'exclude': True}
156
            filter_list.append(f)
157
158
        return filter_list
159