106 строки
2.9 KiB
Ruby
Executable File
106 строки
2.9 KiB
Ruby
Executable File
#!/usr/bin/ruby
|
|
#
|
|
# = Synopsis
|
|
#
|
|
# Use YAML files to provide external node support.
|
|
#
|
|
# = Usage
|
|
#
|
|
# yaml-nodes <host>
|
|
#
|
|
# = Description
|
|
#
|
|
# This is a simple example external node script. It allows you to maintain your
|
|
# node information in yaml files, and it will find a given node's file and produce
|
|
# it on stdout. It has simple inheritance, in that a node can specify a parent
|
|
# node, and the node will inherit that parent's classes and parameters.
|
|
#
|
|
# = Options
|
|
#
|
|
# help::
|
|
# Print this help message
|
|
#
|
|
# yamldir::
|
|
# Specify where the yaml is found. Defaults to 'yaml' in the current directory.
|
|
#
|
|
# = License
|
|
# Copyright 2011 Luke Kanies
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
require 'yaml'
|
|
require 'optparse'
|
|
|
|
BASEDIR = Dir.chdir(File.dirname(__FILE__) + "/..") { Dir.getwd }
|
|
|
|
options = {:yamldir => File.join(BASEDIR, "yaml")}
|
|
OptionParser.new do |opts|
|
|
opts.banner = "Usage: yaml-nodes [options] <host>"
|
|
|
|
opts.on("-y dir", "--yamldir dir", "Specify the directory with the YAML files") do |arg|
|
|
raise "YAML directory #{arg} does not exist or is not a directory" unless FileTest.directory?(arg)
|
|
options[:yamldir] = arg
|
|
end
|
|
|
|
opts.on("-h", "--help", "Print this help") do
|
|
puts opts.help
|
|
exit(0)
|
|
end
|
|
end.parse!
|
|
|
|
# Read in a pure yaml representation of our node.
|
|
def read_node(node)
|
|
nodefile = File.join(YAMLDIR, "#{node}.yaml")
|
|
if FileTest.exist?(nodefile)
|
|
return YAML.load_file(nodefile)
|
|
else
|
|
raise "Could not find information for #{node}"
|
|
end
|
|
end
|
|
|
|
node = ARGV[0]
|
|
|
|
info = read_node(node)
|
|
|
|
# Iterate over any provided parents, merging in there information.
|
|
parents_seen = []
|
|
while parent = info["parent"]
|
|
raise "Found inheritance loop with parent #{parent}" if parents_seen.include?(parent)
|
|
|
|
parents_seen << parent
|
|
|
|
info.delete("parent")
|
|
|
|
parent_info = read_node(parent)
|
|
|
|
# Include any parent classes in our list.
|
|
if pclasses = parent_info["classes"]
|
|
info["classes"] += pclasses
|
|
info["classes"].uniq!
|
|
end
|
|
|
|
# And inherit parameters from our parent, while preferring our own values.
|
|
if pparams = parent_info["parameters"]
|
|
# When using Hash#merge, the hash being merged in wins, and we
|
|
# want the subnode parameters to be the parent node parameters.
|
|
info["parameters"] = pparams.merge(info["parameters"])
|
|
end
|
|
|
|
# Copy over any parent node name.
|
|
if pparent = parent_info["parent"]
|
|
info["parent"] = pparent
|
|
end
|
|
end
|
|
|
|
puts YAML.dump(info)
|