Class: BjnInventory::Util::Filter::JsonAws

Inherits:
BjnInventory::Util::Filter show all
Defined in:
lib/bjn_inventory/util/filter/json_aws.rb

Overview

Implements JSON filtering AWS-style, i.e. similar to how the EC2 API filters instances by tags and attributes when querying.

Instance Method Summary collapse

Methods inherited from BjnInventory::Util::Filter

#initialize, #logger, #select

Constructor Details

This class inherits a constructor from BjnInventory::Util::Filter

Instance Method Details

#_glob2re(str) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/bjn_inventory/util/filter/json_aws.rb', line 35

def _glob2re(str)
    str.scan(/\\\*|\\\?|\?|\*|\\|[^\\\?\*]*/).map do |group|
        case group
        when '\?'
            '\?'
        when '\*'
            '\*'
        when '\\'
            '\\'
        when '*'
            '.*'
        when '?'
            '.'
        else
            Regexp::escape(group)
        end
    end.join('')
end

#_match_filters(entity, filters) ⇒ Object

Since this is an “AWS” style filter, accepts entities with symbols for keys, the way you get when you do an AWS API call and do ‘.to_h`



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/bjn_inventory/util/filter/json_aws.rb', line 70

def _match_filters(entity, filters)
    return true if filters.nil? or filters.empty?
    filter_expr = filters[0]
    name = filter_expr[:name]
    matcher = filter_expr[:matcher]
    this_expr =
        begin
            case name
            when 'tag-key'
                (entity[:tags] || [ ]).any? { |tag| matcher.call tag[:key] }
            when 'tag-value'
                (entity[:tags] || [ ]).any? { |tag| matcher.call tag[:value] }
            when /^tag:/
                tag_key = name[4 .. -1]
                entity_value = (entity[:tags] || [ ]).select { |tag| tag[:key] == tag_key }
                if ! entity_value.empty?
                    matcher.call entity_value[0][:value]
                else
                    false
                end
            else
                matcher.call entity[name.intern]
            end
        rescue StandardError => err
            logger.debug("rejected invalid entity #{entity.inspect}")
            false
        end
    return false unless this_expr

    _match_filters(entity, filters[1 .. -1])
end

#_match_one(expression) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/bjn_inventory/util/filter/json_aws.rb', line 54

def _match_one(expression)
    if /\?|\*/.match expression
        rx  = Regexp.new('\A' + _glob2re(expression) + '\Z')
        proc do |value|
            rx.match value
        end
    else
        proc do |value|
            expression == value
        end
    end
end

#_matcher(values) ⇒ Object



28
29
30
31
32
33
# File 'lib/bjn_inventory/util/filter/json_aws.rb', line 28

def _matcher(values)
    match_one_list = values.map { |expression| _match_one expression }
    proc do |value|
        match_one_list.any? { |match_one| match_one.call value }
    end
end

#match(entity) ⇒ Object



24
25
26
# File 'lib/bjn_inventory/util/filter/json_aws.rb', line 24

def match(entity)
    _match_filters(entity, @filters)
end

#set_options(opt) ⇒ Object



15
16
17
18
19
20
21
22
# File 'lib/bjn_inventory/util/filter/json_aws.rb', line 15

def set_options(opt)
    @filters = JSON.parse(opt[:filters]).map do |filter|
        {
            name: filter['name'],
            matcher: _matcher(filter['values'])
        }
    end
end