Class AutomateIt::TagManager::Struct
In: lib/automateit/tag_manager/struct.rb
Parent: AutomateIt::TagManager::BaseDriver

TagManager::Struct

A TagManager driver for querying a data structure. It‘s not useful on its own, but can be subclassed by other drivers that actually load tags.

Methods

Constants

TAG_NEGATION = %r{!?}
TAG_WORD = %r{[\w\.\-]+}
TAG_TOKENIZER = %r{\!|\(|\)|\&{1,2}|\|{1,2}|#{TAG_NEGATION}#{TAG_WORD}}

Public Instance methods

See TagManager#hosts_tagged_with

[Source]

# File lib/automateit/tag_manager/struct.rb, line 63
  def hosts_tagged_with(query)
    hosts = @struct.values.flatten.uniq
    return hosts.select{|hostname| tagged?(query, hostname)}
  end

Options:

  • :struct — Hash to use for queries.

[Source]

# File lib/automateit/tag_manager/struct.rb, line 14
  def setup(opts={})
    super(opts)
    @struct ||= {}
    @tags   ||= Set.new
    @struct_updated = false
    @our_hostname_tags ||= Set.new
    @our_platform_tags ||= Set.new

    if opts[:struct]
      @struct_updated = true
      @struct.merge!(AutomateIt::TagManager::TagParser.expand(opts[:struct]))
    end
  end

See TagManager#tagged?

[Source]

# File lib/automateit/tag_manager/struct.rb, line 73
  def tagged?(query, hostname=nil)
    query = query.to_s
    selected_tags = hostname ? tags_for(hostname) : tags
    # XXX Tokenizer discards unknown characters, which may hide errors in the query
    tokens = query.scan(TAG_TOKENIZER)
    if tokens.size > 1
      booleans = tokens.map do |token|
        if matches = token.match(/^(#{TAG_NEGATION})(#{TAG_WORD})$/)
          selected_tags.include?(matches[2]) && matches[1].empty?
        else
          token
        end
      end
      code = booleans.join(" ")

      begin
        return eval(code) # XXX What could possibly go wrong?
      rescue Exception => e
        raise ArgumentError.new("Invalid query -- #{query}")
      end
    else
      return selected_tags.include?(query)
    end
  end

Return tags, populate them if necessary.

[Source]

# File lib/automateit/tag_manager/struct.rb, line 29
  def tags
    if @our_hostname_tags.empty?
      @struct_updated = true

      begin
        @our_hostname_tags.merge(interpreter.address_manager.hostnames) # SLOW 0.4s
        @our_hostname_tags.merge(interpreter.address_manager.addresses)
      rescue NotImplementedError => e
        log.debug("Can't find AddressManager for this platform: #{e}")
      end

      @tags.merge(@our_hostname_tags)
    end

    if @our_platform_tags.empty?
      @struct_updated = true

      begin
        @our_platform_tags = interpreter.platform_manager.tags
        @tags.merge(@our_platform_tags)
      rescue NotImplementedError => e
        log.debug("Can't find PlatformManager for this platform: #{e}")
      end
    end

    if @struct_updated
      @tags.merge(tags_for(@our_hostname_tags))
      @struct_updated = false
    end

    @tags
  end

See TagManager#tags_for

[Source]

# File lib/automateit/tag_manager/struct.rb, line 99
  def tags_for(hostnames)
    hostnames = \
      case hostnames
      when String
        interpreter.address_manager.hostnames_for(hostnames)
      when Array, Set
        hostnames.inject(Set.new) do |sum, hostname|
          sum.merge(interpreter.address_manager.hostnames_for(hostname)); sum
        end
      else
        raise TypeError.new("invalid hostnames argument type: #{hostnames.class}")
      end
    result = @struct.inject(Set.new) do |sum, role_and_members|
      role, members = role_and_members
      members_aliases = members.inject(Set.new) do |aliases, member|
        aliases.merge(interpreter.address_manager.hostnames_for(member)); aliases
      end.to_a
      sum.add(role) unless (hostnames & members_aliases).empty?
      sum
    end
    return result.to_a.sort
  end

[Validate]