aboutsummaryrefslogtreecommitdiff
path: root/lib/leap_cli/config.rb
blob: 44e66be86fe8de1ec4691a918bf69800c40f7e20 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
module LeapCli
  #
  # This class represents the configuration for a single node, service, or tag.
  #
  class Config < Hash

    def initialize(config_type, manager)
      @manager = manager
      @type = config_type
    end

    #
    # lazily eval dynamic values when we encounter them.
    #
    def [](key)
      value = fetch(key, nil)
      if value.is_a? Array
        value
      elsif value.nil?
        nil
      else
        if value =~ /^= (.*)$/
          value = eval($1)
          self[key] = value
        end
        value
      end
    end

    #
    # make the type appear to be a normal Hash in yaml.
    #
    def to_yaml_type
     "!map"
    end

    #
    # just like Hash#to_yaml, but sorted
    #
    def to_yaml(opts = {})
      YAML::quick_emit(self, opts) do |out|
        out.map(taguri, to_yaml_style) do |map|
          keys.sort.each do |k|
            v = self.fetch(k)
            map.add(k, v)
          end
        end
      end
    end

    #
    # make obj['name'] available as obj.name
    #
    def method_missing(method, *args, &block)
      if has_key?(method.to_s)
        self[method.to_s]
      else
        super
      end
    end

    #
    # convert self into a plain hash, but only include the specified keys
    #
    def to_h(*keys)
      keys.map(&:to_s).inject({}) do |hsh, key|
        if has_key?(key)
          hsh[key] = self[key]
        end
        hsh
      end
    end

    def nodes
      if @type == :node
        @manager.nodes
      else
        @nodes ||= ConfigList.new
      end
    end

    def services
      if @type == :node
        self['services'] || []
      else
        @manager.services
      end
    end

    def tags
      if @type == :node
        self['tags'] || []
      else
        @manager.tags
      end
    end

    private

    ##
    ## MACROS
    ## these are methods used when eval'ing a value in the .json configuration
    ##

    #
    # inserts the contents of a file
    #
    def file(filename)
      filepath = Path.find_file(name, filename)
      if filepath
        File.read(filepath)
      else
        log0('no such file, "%s"' % filename)
        ""
      end
    end

  end # class
end # module