From ba301b0c8d77ae2f455d3a2d736968c981b8c757 Mon Sep 17 00:00:00 2001 From: elijah Date: Sun, 13 Jan 2013 20:27:29 -0800 Subject: added ability to sync support files along with hiera.yml. this way, files don't need to be embedded in hiera.yml. this is especially useful for binary files. --- lib/leap_cli/config/manager.rb | 32 ++++++++--------- lib/leap_cli/config/node.rb | 52 +++++++++++++++++++++++++++ lib/leap_cli/config/object.rb | 80 +++++++++++++++++++----------------------- lib/leap_cli/config/tag.rb | 18 ++++++++++ 4 files changed, 123 insertions(+), 59 deletions(-) create mode 100644 lib/leap_cli/config/node.rb create mode 100644 lib/leap_cli/config/tag.rb (limited to 'lib/leap_cli/config') diff --git a/lib/leap_cli/config/manager.rb b/lib/leap_cli/config/manager.rb index 6702fc4..c860b5c 100644 --- a/lib/leap_cli/config/manager.rb +++ b/lib/leap_cli/config/manager.rb @@ -21,21 +21,21 @@ module LeapCli @provider_dir = Path.provider # load base - base_services = load_all_json(Path.named_path([:service_config, '*'], Path.provider_base)) - base_tags = load_all_json(Path.named_path([:tag_config, '*'], Path.provider_base)) - base_common = load_json(Path.named_path(:common_config, Path.provider_base)) - base_provider = load_json(Path.named_path(:provider_config, Path.provider_base)) + base_services = load_all_json(Path.named_path([:service_config, '*'], Path.provider_base), Config::Tag) + base_tags = load_all_json(Path.named_path([:tag_config, '*'], Path.provider_base), Config::Tag) + base_common = load_json(Path.named_path(:common_config, Path.provider_base), Config::Object) + base_provider = load_json(Path.named_path(:provider_config, Path.provider_base), Config::Object) # load provider provider_path = Path.named_path(:provider_config, @provider_dir) common_path = Path.named_path(:common_config, @provider_dir) Util::assert_files_exist!(provider_path, common_path) - @services = load_all_json(Path.named_path([:service_config, '*'], @provider_dir)) - @tags = load_all_json(Path.named_path([:tag_config, '*'], @provider_dir)) - @nodes = load_all_json(Path.named_path([:node_config, '*'], @provider_dir)) - @common = load_json(common_path) - @provider = load_json(provider_path) - @secrets = load_json(Path.named_path(:secrets_config, @provider_dir)) + @services = load_all_json(Path.named_path([:service_config, '*'], @provider_dir), Config::Tag) + @tags = load_all_json(Path.named_path([:tag_config, '*'], @provider_dir), Config::Tag) + @nodes = load_all_json(Path.named_path([:node_config, '*'], @provider_dir), Config::Node) + @common = load_json(common_path, Config::Object) + @provider = load_json(provider_path, Config::Object) + @secrets = load_json(Path.named_path(:secrets_config, @provider_dir), Config::Object) # inherit @services.inherit_from! base_services @@ -161,10 +161,10 @@ module LeapCli private - def load_all_json(pattern) + def load_all_json(pattern, object_class) results = Config::ObjectList.new Dir.glob(pattern).each do |filename| - obj = load_json(filename) + obj = load_json(filename, object_class) if obj name = File.basename(filename).sub(/\.json$/,'') obj['name'] ||= name @@ -174,9 +174,9 @@ module LeapCli results end - def load_json(filename) + def load_json(filename, object_class) if !File.exists?(filename) - return Config::Object.new(self) + return object_class.new(self) end log :loading, filename, 2 @@ -201,7 +201,7 @@ module LeapCli log 0, exc.to_s, :indent => 1 return nil end - object = Config::Object.new(self) + object = object_class.new(self) object.deep_merge!(hash) return object end @@ -226,7 +226,7 @@ module LeapCli # makes a node inherit options from appropriate the common, service, and tag json files. # def apply_inheritance(node) - new_node = Config::Object.new(self) + new_node = Config::Node.new(self) name = node.name # inherit from common diff --git a/lib/leap_cli/config/node.rb b/lib/leap_cli/config/node.rb new file mode 100644 index 0000000..9eea1f3 --- /dev/null +++ b/lib/leap_cli/config/node.rb @@ -0,0 +1,52 @@ +# +# Configuration for a 'node' (a server in the provider's infrastructure) +# + +require 'ipaddr' + +module LeapCli; module Config + + class Node < Object + attr_accessor :file_paths + + def initialize(manager=nil) + super(manager) + @node = self + @file_paths = [] + end + + # + # Make a copy of ourselves, except only including the specified keys. + # + # Also, the result is flattened to a single hash, so a key of 'a.b' becomes 'a_b' + # + def pick(*keys) + keys.map(&:to_s).inject(self.class.new(@manager)) do |hsh, key| + value = self.get(key) + if !value.nil? + hsh[key.gsub('.','_')] = value + end + hsh + end + end + + # + # returns true if this node has an ip address in the range of the vagrant network + # + def vagrant? + begin + vagrant_range = IPAddr.new @manager.provider.vagrant.network + rescue ArgumentError => exc + Util::bail! { Util::log :invalid, "ip address '#{@node.ip_address}' vagrant.network" } + end + + begin + ip_address = IPAddr.new @node.get('ip_address') + rescue ArgumentError => exc + Util::log :warning, "invalid ip address '#{@node.get('ip_address')}' for node '#{@node.name}'" + end + return vagrant_range.include?(ip_address) + end + end + +end; end diff --git a/lib/leap_cli/config/object.rb b/lib/leap_cli/config/object.rb index 395ebe3..5c6cfd0 100644 --- a/lib/leap_cli/config/object.rb +++ b/lib/leap_cli/config/object.rb @@ -1,6 +1,5 @@ require 'erb' require 'json/pure' # pure ruby implementation is required for our sorted trick to work. -require 'ipaddr' $KCODE = 'UTF8' unless RUBY_VERSION > "1.9.0" require 'ya2yaml' # pure ruby yaml @@ -17,7 +16,6 @@ module LeapCli attr_reader :node attr_reader :manager - attr_reader :node_list alias :global :manager def initialize(manager=nil, node=nil) @@ -27,9 +25,6 @@ module LeapCli # an object that is a node as @node equal to self, otherwise all the child objects point back to the top level node. @node = node || self - - # this is only used by Config::Objects that correspond to services or tags. - @node_list = Config::ObjectList.new end # @@ -105,21 +100,6 @@ module LeapCli ## COPYING ## - # - # Make a copy of ourselves, except only including the specified keys. - # - # Also, the result is flattened to a single hash, so a key of 'a.b' becomes 'a_b' - # - def pick(*keys) - keys.map(&:to_s).inject(Config::Object.new(@manager,@node)) do |hsh, key| - value = self.get(key) - if !value.nil? - hsh[key.gsub('.','_')] = value - end - hsh - end - end - # # a deep (recursive) merge with another Config::Object. # @@ -195,29 +175,6 @@ module LeapCli self.deep_merge!(object, true) end - ## - ## NODE SPECIFIC - ## maybe these should be moved to a Node class. - ## - - # - # returns true if this node has an ip address in the range of the vagrant network - # - def vagrant? - begin - vagrant_range = IPAddr.new @manager.provider.vagrant.network - rescue ArgumentError => exc - Util::bail! { Util::log :invalid, "ip address '#{@node.ip_address}' vagrant.network" } - end - - begin - ip_address = IPAddr.new @node.get('ip_address') - rescue ArgumentError => exc - Util::log :warning, "invalid ip address '#{@node.get('ip_address')}' for node '#{@node.name}'" - end - return vagrant_range.include?(ip_address) - end - ## ## MACROS ## these are methods used when eval'ing a value in the .json configuration @@ -270,6 +227,43 @@ module LeapCli return nil end + # + # returns what the file path will be, once the file is rsynced to the server. + # an internal list of discovered file paths is saved, in order to rsync these files when needed. + # + # notes: + # + # * argument 'path' is relative to Path.provider/files or Path.provider_base/files + # * the path returned by this method is absolute + # * the path stored for use later by rsync is relative to Path.provider + # * if the path does not exist locally, but exists in provider_base, then the default file from + # provider_base is copied locally. + # + def file_path(path) + if path.is_a? Symbol + path = [path, @node.name] + end + actual_path = Path.find_file(path) + if actual_path.nil? + nil + else + if actual_path =~ /^#{Regexp.escape(Path.provider_base)}/ + # if file is under Path.provider_base, we must copy the default file to + # to Path.provider in order for rsync to be able to sync the file. + local_provider_path = actual_path.sub(/^#{Regexp.escape(Path.provider_base)}/, Path.provider) + FileUtils.cp_r actual_path, local_provider_path + Util.log :created, Path.relative_path(local_provider_path) + actual_path = local_provider_path + end + if Dir.exists?(actual_path) && actual_path !~ /\/$/ + actual_path += '/' # ensure directories end with /, important for building rsync command + end + relative_path = Path.relative_path(actual_path) + @node.file_paths << relative_path + @node.manager.provider.hiera_sync_destination + '/' + relative_path + end + end + # # inserts a named secret, generating it if needed. # diff --git a/lib/leap_cli/config/tag.rb b/lib/leap_cli/config/tag.rb new file mode 100644 index 0000000..e5e719d --- /dev/null +++ b/lib/leap_cli/config/tag.rb @@ -0,0 +1,18 @@ +# +# +# A class for node services or node tags. +# +# + +module LeapCli; module Config + + class Tag < Object + attr_reader :node_list + + def initialize(manager=nil) + super(manager) + @node_list = Config::ObjectList.new + end + end + +end; end -- cgit v1.2.3